@spring-payments/payments-react-native 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Spring Payments for React Native / Expo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Add an **Add debit or credit card** button to your app. It opens a native card-entry form and handles any verification the customer's bank requires. Spring manages the Stripe integration; you do not build card fields or call Stripe yourself.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Your app controls its design and saved-card list. Your backend checks who can use each account and starts payments through Spring. **Saving a card does not charge it.**
|
|
6
|
+
|
|
7
|
+
Supported versions: Expo SDK 57, React Native 0.86 and Stripe React Native 0.64.x. For browser apps, including React Native Web, use `@spring-payments/payments-js` instead. Test real bank verification on your supported iOS/Android devices before going live; passing type checks or simulator UI tests is not enough.
|
|
6
8
|
|
|
7
9
|
Expo SDK 57 requires Node.js 22.13+ and Xcode 26.4+ for local iOS builds ([Expo requirements](https://docs.expo.dev/versions/latest/)). Older Swift compilers reject Expo's `weak let` declarations; upgrade the toolchain rather than patching Expo's Swift sources.
|
|
8
10
|
|
|
@@ -11,7 +13,7 @@ With Xcode 27/iOS 27, SDK 57 apps must also opt into Expo's scene lifecycle: ins
|
|
|
11
13
|
`["expo-build-properties", { "ios": { "enableSceneSupport": true } }]` to your Expo
|
|
12
14
|
plugins. This is app-level Expo setup, not a Spring theme option.
|
|
13
15
|
|
|
14
|
-
## Install
|
|
16
|
+
## Install in an Expo app
|
|
15
17
|
|
|
16
18
|
For Expo SDK 57 / React Native 0.86:
|
|
17
19
|
|
|
@@ -19,9 +21,9 @@ For Expo SDK 57 / React Native 0.86:
|
|
|
19
21
|
npx expo install @spring-payments/payments-react-native @stripe/stripe-react-native@0.64.0
|
|
20
22
|
```
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
Install from npm; do not copy the source, install a supplied archive or load a module from Gateway. No access to Spring's repository is needed. Install the Stripe version shown above because the Spring package relies on its native code, even though your app does not call Stripe directly.
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
Add the Spring plugin to your Expo configuration. **`partnerpayments` is an example, not a required Spring value.** Replace it with a scheme reserved for your app's payment callbacks, such as `acmepayments`:
|
|
25
27
|
|
|
26
28
|
```json
|
|
27
29
|
{
|
|
@@ -31,18 +33,42 @@ Configure your dedicated return scheme, then create/rebuild your development app
|
|
|
31
33
|
}
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
The plugin
|
|
36
|
+
The plugin registers the scheme without removing existing ones. Run `npx expo run:ios`, `npx expo run:android` or your EAS development-build workflow. Rebuilding is required: installing JavaScript or sending an over-the-air update cannot add native code. Use a development build, not Expo Go, for release testing. This card-entry flow does not enable wallets or require an Apple merchant ID.
|
|
37
|
+
|
|
38
|
+
## Install in a React Native app without Expo
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
npm install @spring-payments/payments-react-native @stripe/stripe-react-native@0.64.0
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Run your project's iOS CocoaPods installation, register the payment callback scheme in your iOS/Android configuration and rebuild the apps. The Spring SDK does not require Expo. For either installation method, do not add another `StripeProvider` or initialize Stripe separately while a Spring flow is active.
|
|
45
|
+
|
|
46
|
+
## Before you add the UI
|
|
47
|
+
|
|
48
|
+
Your customer must be registered with Spring, have accepted the required documents and be allowed to add cards. Ask Spring to register your partner, application ID and exact return URL. Sessions are not issued for unregistered destinations.
|
|
35
49
|
|
|
36
|
-
|
|
50
|
+
Use `<your-app-scheme>://safepay` for that URL. Replace `<your-app-scheme>` with your chosen scheme; **keep `://safepay` exactly**, with no trailing slash, extra path, query string or fragment. This address opens your native app after bank verification. It is not a website you need to host.
|
|
51
|
+
|
|
52
|
+
For example, if you choose `acmepayments`, use these matching values:
|
|
53
|
+
|
|
54
|
+
| Where | Value |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| Expo plugin `scheme`, or iOS/Android URL scheme registration | `acmepayments` |
|
|
57
|
+
| Spring SDK `returnUrl` | `acmepayments://safepay` |
|
|
58
|
+
| Exact return URL registered with Spring for your application ID | `acmepayments://safepay` |
|
|
59
|
+
|
|
60
|
+
Your backend needs Spring API credentials. Keep them on the server, never in the app. The component calls your `createSession` function, which asks your backend for a **session**: short-lived permission to add a card or verify one existing payment. Your backend checks the signed-in customer's access before requesting that session from Spring.
|
|
37
61
|
|
|
38
62
|
## One provider and one button
|
|
39
63
|
|
|
64
|
+
`authenticatedPartnerApi`, `refreshSavedCards` and `checkStatusWithYourBackend` below represent code you provide in your app. The SDK does not supply those functions.
|
|
65
|
+
|
|
40
66
|
```tsx
|
|
41
|
-
import { SpringPaymentsProvider, SpringAddCardButton } from '@spring-payments/payments-react-native';
|
|
67
|
+
import { SpringPaymentsProvider, SpringAddCardButton, useSpringPayments } from '@spring-payments/payments-react-native';
|
|
42
68
|
|
|
43
69
|
const options = {
|
|
44
70
|
applicationId: 'com.partner.app',
|
|
45
|
-
returnUrl: 'partnerpayments://safepay',
|
|
71
|
+
returnUrl: 'partnerpayments://safepay', // Replace partnerpayments with your registered scheme.
|
|
46
72
|
gatewayOrigin: 'https://dev.gateway.pay-api.springpayments.com',
|
|
47
73
|
merchantDisplayName: 'Your Business',
|
|
48
74
|
createSession: request => authenticatedPartnerApi.createPaymentSession(request),
|
|
@@ -53,14 +79,14 @@ export function App() {
|
|
|
53
79
|
<SpringPaymentsProvider options={options}>
|
|
54
80
|
<SpringAddCardButton onResult={result => {
|
|
55
81
|
if (result.status === 'COMPLETED') refreshSavedCards();
|
|
56
|
-
if (result.status === 'PENDING')
|
|
82
|
+
if (result.status === 'PENDING') checkStatusWithYourBackend(result);
|
|
57
83
|
}} />
|
|
58
84
|
</SpringPaymentsProvider>
|
|
59
85
|
);
|
|
60
86
|
}
|
|
61
87
|
```
|
|
62
88
|
|
|
63
|
-
Mount one provider above navigation.
|
|
89
|
+
Mount one provider above your app's navigation so it stays mounted while the card form is open. The web and mobile forms look different, but both report success only after Spring confirms the result.
|
|
64
90
|
|
|
65
91
|
## Styling: no Spring theme by default
|
|
66
92
|
|
|
@@ -106,40 +132,46 @@ const themedOptions = {
|
|
|
106
132
|
};
|
|
107
133
|
```
|
|
108
134
|
|
|
109
|
-
|
|
135
|
+
Spring forwards these settings to Stripe without adding a Spring theme. You cannot freely rearrange the form, change the field order or replace secure card inputs. The bank controls its verification screen (often called **3DS**), so you cannot freely redesign that screen either. Web and native Stripe appearance settings have different fields; do not pass the same theme object to both SDKs.
|
|
110
136
|
|
|
111
|
-
For your own button, call `useSpringPayments().addCard()`. To
|
|
137
|
+
For your own button, call `useSpringPayments().addCard()`. To finish verification for an existing payment inside your app, call `useSpringPayments().authenticatePayment(paymentId)`. The hook also provides `busy` and `result`. Do not create a new charge or ask the customer to save another card just to finish verification.
|
|
112
138
|
|
|
113
|
-
##
|
|
139
|
+
## Connect your backend
|
|
114
140
|
|
|
115
|
-
`createSession` receives `{purpose,applicationId,returnUrl,paymentId?}
|
|
141
|
+
`createSession` receives `{purpose, applicationId, returnUrl, paymentId?}`. Call your own authenticated backend with that request. Your backend checks the customer and payment, then calls Spring using its server-side API access token:
|
|
116
142
|
|
|
117
143
|
- Add card: `POST /api/external/spg/v1/clients/{key}/native-card-sessions`
|
|
118
144
|
- Authenticate: `POST /api/external/spg/v1/clients/{key}/payments/{paymentId}/native-authentication-sessions`
|
|
119
|
-
- Both take `{applicationId,returnUrl}` and `Idempotency-Key
|
|
145
|
+
- Both take `{applicationId,returnUrl}` in the body and an `Idempotency-Key` header.
|
|
120
146
|
|
|
121
|
-
Spring
|
|
147
|
+
Return Spring's `{sessionId, sessionToken, expiresAt, componentUrl}` response to the component. Keep these credentials in memory only, not in app storage, URLs, logs or analytics. `gatewayOrigin` limits where the SDK sends the session token. An application ID does not prove who is using the app; your backend must still check the signed-in user.
|
|
122
148
|
|
|
123
|
-
|
|
149
|
+
An **idempotency key** identifies one attempt. Store it on your backend and reuse it when retrying a lost response or returning to the app. This lets Spring return the existing action rather than start another one. Before replacing an expired add-card session, check the saved-account list to see whether the card was already saved. For a payment, check its status before offering another attempt.
|
|
124
150
|
|
|
125
|
-
##
|
|
151
|
+
## Handle results and app restarts
|
|
126
152
|
|
|
127
153
|
- **COMPLETED**: Spring confirmed the saved account or original payment. Add-card includes `paymentAccountId`; authentication includes `paymentId`. A native sheet's success alone is not completion.
|
|
128
|
-
- **PENDING**:
|
|
129
|
-
- **FAILED**:
|
|
130
|
-
- **CANCELLED**
|
|
154
|
+
- **PENDING**: Spring has not confirmed the outcome after checking up to 10 times. The result includes `sessionId` and, for payment verification, `paymentId`. Ask your backend to check the same action; do not start a duplicate.
|
|
155
|
+
- **FAILED**: The flow could not continue. The code is `UNAVAILABLE`, `EXPIRED` or `REJECTED`; raw Stripe errors and credentials are not returned.
|
|
156
|
+
- **CANCELLED** means the SDK knows nothing was submitted. Closing the native form does not establish that: the customer may already have pressed Save. The SDK checks with Spring and can return `COMPLETED` or `PENDING` instead. Do not tell the customer that nothing was saved simply because they closed the form.
|
|
157
|
+
|
|
158
|
+
Only one card or verification form can be open at a time. Repeated calls for the same action share its result; a different action returns `UNAVAILABLE` while the first is active. Do not switch customers or change the provider's session settings while a form is open.
|
|
159
|
+
|
|
160
|
+
Use `<your-scheme>://safepay` as the payment return URL; the `safepay` suffix is required by the iOS integration. The SDK handles the iOS link callback and Stripe handles the native Android return. Keep this route separate from your normal navigation and analytics, and never log its query parameters.
|
|
161
|
+
|
|
162
|
+
If the operating system closes your app, its in-memory session is lost. Restore the customer's sign-in, check the original action through your backend and call `createSession` again only as needed. Opening a return link does not prove success. Your app is responsible for getting the customer's consent to future charges and asking them to return when a payment needs verification.
|
|
131
163
|
|
|
132
|
-
|
|
164
|
+
## Spring-hosted payment recovery (preferred)
|
|
133
165
|
|
|
134
|
-
|
|
166
|
+
For a customer returning to finish an existing payment, Spring's hosted browser recovery page is the preferred option. It opens a Spring page; it does not load a component into your app. Use this npm package for card entry and payment verification inside your app.
|
|
135
167
|
|
|
136
|
-
|
|
168
|
+
Open a page on your website where the customer can sign in. Your backend checks that they own the original payment and creates a **web** authentication session using the Gateway origin and `{gatewayOrigin}/payment-components/recover` as the return URL. Your page submits `sessionId` and `sessionToken` to Spring in a browser form POST body. Never put session credentials in a deep link or URL, and never send a native session to the web recovery page. Returning to the app is not proof of payment; ask your backend to check the original payment's status. If you prefer verification inside the app, use `authenticatePayment(paymentId)` as described above.
|
|
137
169
|
|
|
138
|
-
##
|
|
170
|
+
## Test before going live
|
|
139
171
|
|
|
140
|
-
|
|
172
|
+
Test your integration on both iOS and Android with your configured backend. Check saving a card, completing and cancelling bank verification, switching apps, restarting after the operating system closes your app, screen-reader access and larger text sizes. Confirm that the card form does not offer saved cards, Link or wallets. Check that your app handles payment notifications arriving later than the form's result.
|
|
141
173
|
|
|
142
|
-
|
|
174
|
+
The 0.1.x releases are initial integration releases, not certification of a live payment flow. iOS simulator Release build and styled/unstyled UI checks have passed; actual PaymentSheet/3DS with a configured backend and Android native verification remain outstanding. Complete those checks before a production integration.
|
|
143
175
|
|
|
144
176
|
## License
|
|
145
177
|
|
|
@@ -147,7 +179,7 @@ MIT; see [LICENSE](./LICENSE). This license covers the Spring code in this SDK p
|
|
|
147
179
|
|
|
148
180
|
## Maintaining and publishing (Spring maintainers)
|
|
149
181
|
|
|
150
|
-
Source of truth: `packages/spring-payments-react-native/` in the private `ktechgit/spring-payments` repository. Edit `src/`, `app.plugin.js` and this README here. `dist/` is generated; do not edit it. The repository's `examples/embedded-partner-expo/` is the integration consumer, not the package source.
|
|
182
|
+
Source of truth: `packages/spring-payments-react-native/` in the private `ktechgit/spring-payments` repository. Edit `src/`, `app.plugin.js` and this README here. `dist/` is generated; do not edit it. The repository's `examples/embedded-partner-expo/` is the integration consumer, not the package source. Local tarballs below are for maintainer release validation only, not an alternative partner installation route.
|
|
151
183
|
|
|
152
184
|
From this directory:
|
|
153
185
|
|
|
@@ -165,8 +197,8 @@ For subsequent releases, choose a semantic version and run `npm version patch --
|
|
|
165
197
|
Authenticate interactively with `npm login --registry=https://registry.npmjs.org/`; confirm the account with `npm whoami` and its publish access to `@spring-payments`. Keep npm credentials in the maintainer/build environment only. With release authorization, publish the exact inspected tarball (replace the version in its filename):
|
|
166
198
|
|
|
167
199
|
```sh
|
|
168
|
-
npm publish ./spring-payments-payments-react-native-0.1.
|
|
169
|
-
npm view @spring-payments/payments-react-native@0.1.
|
|
200
|
+
npm publish ./spring-payments-payments-react-native-0.1.2.tgz --access public --registry=https://registry.npmjs.org/
|
|
201
|
+
npm view @spring-payments/payments-react-native@0.1.2 version license dist.integrity --registry=https://registry.npmjs.org/
|
|
170
202
|
```
|
|
171
203
|
|
|
172
204
|
For a preview release, use a prerelease version and `--tag next`; do not move `latest` inadvertently. After registry verification, install the published version in the Expo demo, regenerate its lockfile, run its typecheck and Expo configuration check, and update partner installation instructions. An npm release does not deploy Gateway configuration, authorize a native application or complete device/processor certification.
|