npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thefaithapp/giving-react-native

v0.1.0

Published

Authenticated general and campaign giving UI for React Native and Expo apps.

Readme

TheFaithApp Giving for React Native

@thefaithapp/giving-react-native adds authenticated general and campaign giving to React Native and Expo apps. It renders the giving form, the church's active payment method, campaign custom fields, and the payment experience for Stripe, PayPal, and Flutterwave.

TheFaithApp creates the donation, derives the member and client identity from the authenticated session, receives provider webhooks, and owns the final payment status.

Install

npm install @thefaithapp/auth-react-native @thefaithapp/giving-react-native
npx expo install @stripe/stripe-react-native react-native-webview
npx expo install expo-application expo-crypto expo-secure-store expo-web-browser

Add the auth and Stripe plugins to app.json. Stripe requires an options object even when Apple Pay and Google Pay are not enabled:

{
  "expo": {
    "scheme": "your-church",
    "plugins": [
      "@thefaithapp/auth-react-native",
      [
        "@stripe/stripe-react-native",
        {
          "merchantIdentifier": "merchant.com.example.church",
          "enableGooglePay": false
        }
      ],
      "expo-secure-store",
      "expo-web-browser"
    ],
    "ios": {
      "bundleIdentifier": "com.example.church"
    },
    "android": {
      "package": "com.example.church"
    }
  }
}

Rebuild the native application after adding the native dependencies. Stripe PaymentSheet cannot run inside Expo Go.

Create the clients

import { TheFaithAppAuth } from '@thefaithapp/auth-react-native'
import {
  TheFaithAppGiving,
  createStripeGivingPaymentHandler,
} from '@thefaithapp/giving-react-native'

const auth = new TheFaithAppAuth({ apiKey: 'your-client-key' })

const giving = new TheFaithAppGiving({
  auth,
  paymentHandlers: [
    createStripeGivingPaymentHandler({
      urlScheme: 'your-church',
      returnUrl: 'your-church://stripe-redirect',
    }),
  ],
})

The custom Stripe registration replaces the built-in Stripe handler with the same provider ID and adds an app return URL for redirect and 3DS flows. If the application only supports flows that do not leave PaymentSheet, the default handler can be used without this override.

A member must have a valid auth session before protected giving calls succeed:

await auth.signIn()

General giving

import { GeneralGivingView } from '@thefaithapp/giving-react-native'

export function GivingScreen() {
  return (
    <GeneralGivingView
      giving={giving}
      onCompleted={(result) => {
        // result.state: succeeded, pending, failed, or cancelled
      }}
      onError={(error) => {
        // Present a safe error. Do not log checkout session values.
      }}
    />
  )
}

The view loads available funds, supports splitting a gift between funds, currency, recurring frequency, memo, and fee coverage according to the church's configuration.

Campaign giving

import { CampaignGivingView } from '@thefaithapp/giving-react-native'

export function CampaignScreen({ campaignId }: { campaignId: number }) {
  return (
    <CampaignGivingView
      campaignId={campaignId}
      giving={giving}
      onCompleted={(result) => {
        // The platform/webhook status is reflected in result.state.
      }}
    />
  )
}

The campaign view loads the campaign and renders its configured text, textarea, number, email, tel, select, radio, checkbox, and date fields. Campaign discovery or a campaign ID selector belongs to the host application, not this package.

Both views accept partial strings overrides, contentContainerStyle, allowRecurring, and showMemo.

Custom payment methods

Payment presentation is provider-extensible. A handler receives only an ephemeral checkout session and narrow completion capabilities—never the auth client, API key, bearer token, member ID, or client ID.

import type {
  GivingPaymentHandler,
  GivingPaymentHandlerProps,
} from '@thefaithapp/giving-react-native'

function ChurchPay({
  checkout,
  onComplete,
  onError,
}: GivingPaymentHandlerProps) {
  // Present provider UI. Do not persist or log checkout.session.
  // Confirm through checkout.waitForAuthoritativeStatus() before completing.
  return null
}

const churchPayHandler: GivingPaymentHandler = {
  provider: 'church-pay',
  Component: ChurchPay,
}

const giving = new TheFaithAppGiving({
  auth,
  paymentHandlers: [churchPayHandler],
})

The handler's provider must exactly match the active provider returned by TheFaithApp. Custom handlers with stripe, paypal, or flutterwave replace the corresponding built-in handler.

Headless checkout

The rendered views are optional. A custom UI can create a protected checkout and render GivingPaymentHandlerHost:

const checkout = await giving.createGeneralCheckout({
  allocations: [{ amount: 25, fundId: 4 }],
  currency: 'USD',
  frequency: 'one_time',
})

<GivingPaymentHandlerHost
  giving={giving}
  checkout={checkout}
  onComplete={setResult}
  onError={setError}
/>

For campaigns, call createCampaignCheckout(campaignId, request).

Keep the host mounted until it completes. If a custom flow dismisses a checkout without rendering the host, call:

await giving.abandonCheckout(checkout)

Security model

  • Giving calls use authorizedFetch from @thefaithapp/auth-react-native.
  • The SDK accepts no member ID, client ID, API key, or bearer token fields.
  • Authenticated calls are relative paths; the auth package restricts them to TheFaithApp's API origin.
  • Stripe client secrets and hosted approval URLs are ephemeral and are never stored by the SDK.
  • PayPal and Flutterwave callbacks must match the exact API origin, expected callback path, and donation ID.
  • A provider UI returning success is not proof of payment. The SDK polls the platform's webhook-backed status.
  • Cancelled, invalid, dismissed, and failed hosted checkouts trigger best-effort abandonment. Platform-side checkout expiry is the fallback when a device is offline or terminated.
  • Provider webhooks and signing secrets remain on TheFaithApp. They do not belong in the mobile application.

License

TheFaithApp Giving is available under the MIT License.