GitHub – freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.

Что такое stripe?

Stripe – это финансовый и программный сервис, который помогает разработчикам программного обеспечения и компаниям, занимающимся электронной коммерцией, осуществлять беспрепятственные платежи через свой API. Вы можете назвать Stripe компанией, предлагающей программное обеспечение как услугу (SaaS).

Поскольку финтех продолжает получать покровительство со стороны новых и существующих SaaS-компаний по всему миру, каждая третья платная услуга, выпущенная в Интернете, использует Stripe в качестве способа оплаты. Глубокое знание того, как интегрировать Stripe в ваше приложение React Native, будет лучшим способом уменьшить хлопоты, связанные с интеграцией платежей в ваши приложения для iOS и Android.

>= 0.60

Autolinking will just do the job.

Add-ons

Here’s a list of Payment Processors that you can enable via add-ons:

🚨Note: On Android, Payment Processors are enabled by default.

Android

npx jetify

Api spec

Down below we have a detailed specification for PaymentRequest and instructions for configuring Apple Pay and Google Pay, which is hopefully enough to get you started.

We also have some legacy example projects in the examples directory that will be rewritten soon and linked above.

Bear with us while we organize things a bit.

Apple pay payment type values

ConstantTypeValueDescription
PaymentTypePendingint1A summary item representing an estimated or unknown cost.
PaymentTypeFinalint2A summary item representing the known, final cost.

Apple pay и другие способы оплаты

SDK поддерживает несколько вариантов оплаты, таких как банковские переводы, дебетование и переадресация; кредитные карты; купи сейчас, заплати потом; ваучеры; и цифровые кошельки. Он также поддерживает Apple Pay. Вы можете прочитать официальную документацию Stripe по интеграции Apple Pay здесь, а также о том, как интегрировать другие способы оплаты здесь.

Applepaycompletecallback

iOS Only

Callback invoked when the native iOS Apple Pay payment authorization sheet is closed with success, failure, or cancellation.

This callback notifies caller widget when it should switch to other views.

Applepayconfig

Represents the Apple Pay configuration.

Applepaynoncerequestfailurecallback

iOS Only

Callback invoked when a card nonce cannot be generated from Apple Pay payment authorization card input values.

Applepaynoncerequestsuccesscallback

iOS Only

Callback invoked when Apple Pay card details are available

This is called before the Apple Pay payment authorization sheet is closed. Call completeApplePayAuthorization
to close the apple pay sheet.

Brand

Supported brands for card payments accepted during the In-App Payments SDK checkout
flow.

  • VISA – Visa Inc. credit or debit card.
  • MASTERCARD – Mastercard Incorporated credit or debit card.
  • AMERICAN_EXPRESS – American Express Company credit card.
  • DISCOVER – Discover Financial Services credit card.
  • DISCOVER_DINERS – Diners Club International credit card.
  • JCB – Japan Credit Bureau credit card.
  • CHINA_UNION_PAY – China UnionPay credit card.
  • OTHER_BRAND – An unexpected card type.

Building a card component

To begin, create a new folder named screens within the root directory of your React Native app.

Navigate into the folder and create a new file called paymentScreen.js, then paste in the code below:

Buyerverificationdetails

Represents the result of a successful buyer verification request.

Buyerverificationerrorcallback

Callback invoked when Buyer Verification flow fails.

Buyerverificationsuccesscallback

Callback invoked when Buyer Verification flow succeeds.

Canuseapplepay

iOS Only

Canusegooglepay

Android Only

Cardentrycancelcallback

Callback invoked when card entry canceled and has been closed.

Do not call completeCardEntry because the operation is complete and the card entry form is closed.

Cardentrycompletecallback

Callback invoked when card entry is completed and has been closed.

Cardentryconfig

Represents the Card Entry configuration.

Cardentrynoncerequestsuccesscallback

Callback invoked when card entry is returned successfully with card details.

Cardprepaidtype

The prepaid type of the credit card (for example, a Prepaid Gift Card). Note: This property is experimental and will always return UNKNOWN

  • PREPAID – Prepaid card.
  • NOT_PREPAID – Card that is not prepaid.
  • UNKNOWN – Unable to determine whether the card is prepaid or not.

Cardtype

The type of card (for example, Credit or Debit). Note: This property is experimental and will always return UNKNOWN.

  • DEBIT – Debit card.
  • CREDIT – Credit card.
  • UNKNOWN – Unable to determine type of the card.

Cocoapods

Link using Cocoapods by adding this to your Podfile:

Completeapplepayauthorization

iOS Only

Notifies the native layer to close the Apple Pay sheet with success or failure status.

ParameterTypeDescription
isSuccessboolIndicates success or failure.
Optional: errorMessageStringThe error message that Apple Pay displays in the native layer card entry view controller.

Completecardentry

Called in the onCardNonceRequestSuccess callback. Closes the card entry form.

completeCardEntry should be called after all other callback logic is executed.
If callback logic makes a server call to process the supplied nonce,
this method is called after getting a success response from the server.

If any nonce processing logic is to be executed after the card entry form is closed,
call completeCardEntry after getting the card nonce from the onCardNonceRequestSuccesscardDetails parameter.

Connect firebase to your firebase project

You can create a Firebase Project in Firebase console webpage, and invoke it in development environment (your system) 

Once you have your project ready, connect it to your dev environment using

$ firebase init

then choosing the project, and choosing functions option from the choices.

Choose Functions options in `Firebase init`

With Firebase Functions, you can essentially right back-end (node.js) functions in same environment, test locally with firebase serve and can then deploy these to your Firebase project, so it can be connected to your app / website.

Once you have Firebase project connected, you will see a functions folder in your project root, as shown below

Firebase functions folder in project root

Contributors

Many people have contributed to the development of react-native-payments over time. The people below are currently available to help.

Create a firebase function to make payment requests

After this, you can create your back-end function in functions/index.js file. This function will accept a request object from your app / website, send the payment request to Stripe server, and return the response to your app / website again.

Firebase function to complete payment using Stripe

Remember to replace YOUR_SECRET_KEY with your own.

Notice that the payment request from your app should contain

This data should be sent in an object in POST API request, shown in next step.

Create paymentmethod with apple pay · issue #271 · stripe/stripe-react-native

Is your feature request related to a problem? Please describe.
When creating a subscription for a customer with a debit card, it is clear and straightforward that the payment method is stored with the subscription and associated with the customer object. You can either create a PaymentMethod using the card information and associate it with the subscription in that manner, or you can pass in setupFutureUsage: 'OffSession' to confirmPayment() to associate the card information.

When paying with Apple Pay, it is not clear that the Apple Pay payment method is being associated with the subscription. I create a subscription on the server side and pass in payment_behavior: "default_incomplete", and then call confirmApplePayPayment() on the frontend. Do I just trust that the payment method will be associated and charged again when the customer’s subscription auto-renews?

Describe the solution you’d like
Allow us to create Apple Pay tokens and create PaymentMethods with them, as noted by Stripe documentation here:
https://support.stripe.com/questions/using-apple-pay-for-recurring-payments

Or add a setupFutureUsage field to the confirmApplePayPayment() so that we can be sure that the customer’s payment method is associated with their subscription.

Describe alternatives you’ve considered
Use confirmApplePayPayment() with a payment_intent secret from the server-side subscription object and hope that the payment associates itself.

Additional context
My main concern here is with changing payment methods on the customer’s subscription if the customer has a subscription with no PaymentMethod attached to their customer object. What would happen if we called (server-side)

await stripeClient.subscriptions.update(stripeSubscriptionId, {
  payment_behavior: "default_incomplete",
});

for an Apple Pay payment whose payment_intent never gets confirmed on the frontend? In my mind, if this happened with a debit card payment, at least the associated PaymentMethod attached to the customer object would be a fallback method for payment, but would this wipe the Apple Pay payment method off of the subscription object?

Deploy firebase function to live site

Once your local testing is successful, deploy the firebase functions to live server using

$ firebase deploy --only functions

This will deploy the functions on your live Firebase server, which you can make API calls to. The url of the function will again be shown in the terminal after deployment, something like

Displaying the payment request

Now that you’ve setup your Payment Request, displaying it is as simple as calling the show method.

See Screenshots

GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.

Error

Contains information about a payment card processing error.

Example json

{
  "font": {
    "size": 30,
  },
  "backgroundColor" :{
    "r": 239,
    "g": 239,
    "b": 244,
    "a": 1.0,
  },
  "foregroundColor" :{
    "r": 255,
    "g": 255,
    "b": 255,
  },
  "textColor" :{
    "r": 0,
    "g": 0,
    "b": 0,
    "a": 0.9,
  },
  "placeholderTextColor" :{
    "r": 0.72,
    "g": 0.72,
    "b": 0.75,
    "a": 1.00,
  },
  "tintColor" :{
    "r": 0,
    "g": 122,
    "b": 254,
    "a": 1,
  },
  "messageColor" :{
    "r": 0.72,
    "g": 0.72,
    "b": 0.75,
    "a": 1.0,
  },
  "errorColor" :{
    "r": 139,
    "g": 0,
    "b": 12,
    "a": 0.9,
  },
  "saveButtonTitle": "Pay 💳 ",
  "saveButtonFont" : {
    "size": 30,
    "name": "courier",
  },
  "saveButtonTextColor": {
    "r": 213,
    "g": 133,
    "b": 12,
    "a": 0.9,
  },
  "keyboardAppearance": "Light",
}

Example usage

import{SQIPCardEntry}from'react-native-square-in-app-payments';constpaymentSourceId='ccof:customer-card-id-requires-verification';constcardEntryConfig={collectPostalCode: true,squareLocationId: SQUARE_LOCATION_ID,buyerAction: 'Charge',amount: 100,currencyCode: 'USD',givenName: 'John',familyName: 'Doe',addressLines: ['London Eye','Riverside Walk'],city: 'London',countryCode: 'GB',email: 'johndoe@example.com',phone: '8001234567',postalCode: 'SE1 7'};awaitSQIPCardEntry.startBuyerVerificationFlow(paymentSourceId,cardEntryConfig,(buyerVerificationDetails)=>{ ... },// onBuyerVerificationSuccess(errorInfo)=>{ ... },// onBuyerVerificationFailure()=>{ ... },// onCardEntryCancel);

Generate token on app

To generate token, import the library in your page using

$ import stripe from 'tipsi-stripe'

And initialize it with your Stripe credentials that you can get from dashboard.

stripe.setOptions({
publishableKey: 'PUBLISHABLE_KEY'
})

Remember, PUBLISHABLE_KEY only helps in generating token. Replace this with your own PUBLISHABLE_KEY 

We will use the paymentRequestWithCardForm method of the library to get the Token (Check CardFormScreen.js file for full details)

Method to generate Token using Stripe

The method will open the “Default card details form” for Stripe. Enter your card details here (or use a sample cards from Stripe), and enter your address and submit. 

Once you submit the details, you will receive a token from Stripe. I have the token displayed in the UI like this, for confirmation

Received token from Stripe — Sample React Native app

Gettotal(summaryitems)

Returns the total charge of the summary items.

Example

Google pay environment values

ConstantTypeValueDescription
EnvironmentProductionint1Environment to be used when an app is granted access to the Google Pay production environment.
EnvironmentTestint3Environment to be used for development and testing an application before approval for production.

Googlepaycancelcallback

Android Only

Callback invoked when Google Pay payment authorization is canceled.

Googlepayconfig

Represents the Google Pay configuration.

Googlepaynoncerequestfailurecallback

Android Only

Callback invoked a card nonce could not be obtained.

Googlepaynoncerequestsuccesscallback

Android Only

Callback invoked when cardDetails with Google Pay are available.

How does stripe work ?

To simplify the understanding, let us understand the complete flow pictorially

Stripe Payment integration flow

Essentially, in front-end (App side) we initiate a payment. This requests for a token from Stripe server. Once this token is received on front-end, you need to send it to your server (back-end). Only your server can communicate to Stripe server for actual payment.

In progress

  • Stripe: Payment Intents (for SCA)

Inapppaymentsexception

Signals that card entry exception of some sort has occurred. This
class is the general class of exceptions produced by failed payment card
processing operations.

Install

npm i --save react-native-apple-pay

Iostheme

Encapsulates options used to style the iOS native card entry view controller.

FieldTypeDescription
Optional: fontFontThe text field font.
Optional: backgroundColorRGBAColorThe background color of the card entry view controller.
Optional: foregroundColorRGBAColorThe fill color for text fields.
Optional: textColorRGBAColorThe text field text color.
Optional: placeholderTextColorRGBAColorThe text field placeholder text color.
Optional: tintColorRGBAColorThe tint color reflected in the text field cursor and submit button background color when enabled.
Optional: messageColorRGBAColorThe text color used to display informational messages.
Optional: errorColorRGBAColorThe text color when the text is invalid.
Optional: saveButtonTitleStringThe text of the entry completion button
Optional: saveButtonFontFontThe save button font.
Optional: saveButtonTextColorRGBAColorThe save button text color when enabled.
Optional: keyboardAppearanceKeyboardAppearanceThe appearance of the keyboard.

Join us!

All contributions, big or small are welcomed.

For large PRs, please open an issue and have a discussion with us first before you dive in.

Our plan for this library is for it to be useful to all React Native developers so we want to architect it carefully.

License

Copyright (c) 2022, Naoufal Kadhom, Igor Shmukler

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Link the package

Run react-native link tipsi-stripe to link the package against your Xcode project and so that all CocoaPods dependencies are installed.

Note: Linking on Windows system currently isn’t working, sadly. Check here for updates

Live demo

For a step by step guide, check out this talk by @naoufal.

Paymentrequest(merchantoptions, paymentitems)

Initializes Apple Pay. NOTE that paymentRequest adds one entry to the paymentItems array – summary, where label is set to merchantName and amount is sum of all amount values in the original array.

Arguments

  • merchantOptions – An Object that will be served to setup the payment request.
  • summaryItems – An Array containing the items the customer will be purchasing.

merchantOptions

summaryItem

  • label – A String representing the summary name.
  • amount – A Number with two decimal places representing the summary price.

Example

varmerchantOptions={paymentProcessor: 'stripe',paymentProcessorPublicKey: 'pk_test_QsubAYNpjqwertyAogowi9r7',merchantIdentifier: 'merchant.yourapp.you',merchantName: "Company, Inc.",supportedNetworks: ['PKPaymentNetworkMasterCard','PKPaymentNetworkVisa'],merchantCapabilities: ['PKMerchantCapability3DS','PKMerchantCapabilityEMV'],countryCode: 'US',currencyCode: 'USD'};varsummaryItems=[{label: 'Hockey Stick',amount: 88.88}];ApplePay.paymentRequest(merchantOptions,summaryItems).then(chargeTokenOnServer).then(ApplePay.success).catch(error=>{// Log errorApplePay.failure();});functionchargeTokenOnServer(token){...}

Processing payments on your server

If you’re equipped to process Apple Pay/Android Pay payments on your server, all you have to do is send the Payment Response data to your server.

⚠️ Note: When running Apple Pay on simulator, paymentData equals to null.

import { NativeModules } from 'react-native';

paymentRequest.show()
  .then(paymentResponse => {
    const { transactionIdentifier, paymentData } = paymentResponse.details;

    return fetch('...', {
      method: 'POST',
      body: {
        transactionIdentifier,
        paymentData
      }
    })
    .then(res => res.json())
    .then(successHandler)
    .catch(errorHandler)
  });
See Android Pay Example
paymentRequest.show()
  .then(paymentResponse => {
    const { getPaymentToken } = paymentResponse.details;

    return getPaymentToken()
      .then(paymentToken => {
        const { ephemeralPublicKey, encryptedMessage, tag } = paymentResponse.details;

        return fetch('...', {
          method: 'POST',
          body: {
            ephemeralPublicKey,
            encryptedMessage,
            tag
          }
        })
        .then(res => res.json())
        .then(successHandler)
        .catch(errorHandler)
      });
  });

You can learn more about server-side decrypting of Payment Tokens on Apple’s Payment Token Format Reference documentation.

Processing payments with a payment processor

When using a payment processor, you’ll receive a paymentToken field within the details of the PaymentResponse. Use this token to charge customers with your payment processor.

paymentRequest.show()
  .then(paymentResponse => {
    const { paymentToken } = paymentResponse.details; // On Android, you need to invoke the `getPaymentToken` method to receive the `paymentToken`.

    return fetch('...', {
      method: 'POST',
      body: {
        paymentToken
      }
    })
    .then(res => res.json())
    .then(successHandler)
    .catch(errorHandler);
  });
See Android Pay Example
paymentRequest.show()
  .then(paymentResponse => {
    const { getPaymentToken } = paymentResponse.details;

    return getPaymentToken()
      .then(paymentToken => fetch('...', {
        method: 'POST',
        body: {
          paymentToken
        }
      })
      .then(res => res.json())
      .then(successHandler)
      .catch(errorHandler);
    });
  });

For a list of supported payment processors and how to enable them, see the Add-ons section.

React native and stripe

React Native can create a wide variety of apps, and hence a wide variety of payment gateways can be implemented in React Native apps. The popular ones are PayPal, Stripe, RazorPay, Braintree, in-app purchase etc.

There are two options for front-end implementation of Stripe in React Native apps

  1. Use the iOS / Android SDKs provided by Stripe
  2. Use a 3rd party library for React Native: tipsi-stripe

There are pros and cons to each path, mainly revolving around the fact that the React Native library from Tipsi has not been “publicly” approved by Stripe. If you want maximum compliance in production environment, go for Stripe’s fully vetted SDKs.

React native payments

Accept Payments with Apple Pay and Android Pay using the Payment Request API.

Features

  • Simple. No more checkout forms.
  • Effective. Faster checkouts that increase conversion.
  • Future-proof. Use a W3C Standards API, supported by companies like Google, Firefox and others.
  • Cross-platform. Share payments code between your iOS, Android, and web apps.
  • Add-ons. Easily enable support for Stripe or Braintree via add-ons.

Requestapplepaynonce

iOS Only

Starts the Apple Pay payment authorization and returns a nonce based on the authorized Apple Pay payment token.

Throws InAppPaymentsException

Requestgooglepaynonce

Android Only

Starts the Google Pay payment authorization and returns a nonce based on the authorized Google Pay payment token.

Throws InAppPaymentsException

Requesting a contact name

Set requestPayerName to true to request a contact name.

See Screenshots

GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.

Requesting a phone number

Set requestPayerPhone to true to request a phone number.

See Screenshots

GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.

Requesting a shipping address

Requesting a shipping address is done in three steps.

First, you’ll need to set requestShipping to true within PaymentOptions.

Second, you’ll need to include shippingOptions in your Payment Details.

const DETAILS = {
  id: 'basic-example',
  displayItems: [
    {
      label: 'Movie Ticket',
      amount: { currency: 'USD', value: '15.00' }
    }
  ],
  shippingOptions: [{    id: 'economy',    label: 'Economy Shipping',    amount: { currency: 'USD', value: '0.00' },    detail: 'Arrives in 3-5 days' // `detail` is specific to React Native Payments  }],
  total: {
    label: 'Merchant Name',
    amount: { currency: 'USD', value: '15.00' }
  }
};

Requesting an email address

Set requestPayerEmail to true to request an email address.

See Screenshots

GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.GitHub - freeman-industries/react-native-payments-example-ios: Clone this to try using react-native-payments on iOS.

You can also request all three by setting them all to true.

Sca-ready

The SDK by default performs a 3D authentication in compliance with Strong Customer Authentication offered by Stripe. Read more about card authentication and 3D secure in Stripe here.

Sdk stripe react native

Теперь, когда вы понимаете, что такое Stripe, лучший способ начать работу с Stripe API – это прочитать официальную документацию Stripe здесь.

Но знаете что? SDK Stripe React Native может сократить этот процесс примерно на 60%.

Давайте изучим Stripe React Native SDK и посмотрим, что он может предложить. Ниже приведен список функций, поставляемых с выпуском v0.1.2.

Setsquareapplicationid

Used to set a Square Application ID on the InAppPaymentsSDK object.

Setup

npm install

cd ios
pod install


npm run ios

Setup firebase cloud function

Assumption — You already know how to create a Firebase Project, and deploy Firebase function on it. You can follow my blogs on how to create a Firebase project (first few steps) and how to create Firebase Cloud functions.

To interact with Firebase functions in development, you need Firebase-tools in your system. Install firebase tools with

$ npm install -g firebase-tools

Setup pods

To integrate appropriate pods for iOS app, setup your Podfile like the following then run pod install. My Podfile looks like this

Podfile to setup tipsi-stripe in React Native

Setup xcode project

  1. Open your project in Xcode workspace.
  2. Drag the following folder into your project:
Tipsi-stripe node_modules dragged into Xcode project

Showcardnonceprocessingerror

Called in the onCardNonceRequestSuccess callback. Returns execution to the card entry form
with an error string to be shown in the form.

showCardNonceProcessingError should be called after all other callback logic is executed.
If callback logic makes a server call to request a payment with the supplied nonce,
this method is called after getting an error response from the server call.

ParameterTypeDescription
errorMessageStringThe error message to be shown in the card entry form.

Startcardentryflowwithbuyerverification

Displays a full-screen card entry view with buyer verification flow enabled. The method takes one configuration object and three call back parameters which correspond
to the possible results of the request.

Step 2— create a basic react native app

First, make sure you have all pre-requisites to create a react-native app as per the official documentation.

At the time of this post, I have React-Native version 0.60

Create a blank react-native app (Replace RNStripe with your own app name)

$ react-native init RNStripe

This will create a basic React-native app which you can run in a device or simulator. Let’s run the app in iOS using

$ react-native run-ios

You’ll see the default start screen on device / simulator. For sample purpose, I will be using the UI provided by tipsi-stripe library. It has options for all kinds of payments — including Apple Pay, Google Pay etc. I’ll be using the default card payment form for this post’s purpose

tipsi-stripe UI example layouts

There are three major files used for this example

You can find these files in the Github repo attached to this post.

Step 3 — integrate stripe library tipsi-stripe for token generation

To include Stripe functionality in your React Native app, you need to install tipsi-stripe package. Install the package with following commands

$ npm install --save tipsi-stripe

Steps to implement

I will break it down into steps to keep the post organized

Step 1 — Stripe Developer account and API keys

Step 2 — Create a basic React Native app for Stripe integration

Step 3— Integrate Stripe library tipsi-stripe for token generation

Step 4— Create Firebase function (or any back-end function to accept API calls) to accept tokens from app, and make payment requests to Stripe server

Step 5— Connect app to our Firebase server. Complete Stripe payment requests from Firebase server.

Let’s start step-by-step

Complete source code of this tutorial is available in the RNStripe Github repository

Test firebase functions locally

To test whether your Firebase function is correctly written, run the function locally by running command

$ firebase serve

This will start your firebase local server, and the url will be displayed in the terminal , something like

Usage

import{ApplePay}from'react-native-apay';constrequestData={merchantIdentifier: 'merchant.com.example',supportedNetworks: ['mastercard','visa'],countryCode: 'US',currencyCode: 'USD',paymentSummaryItems: [{label: 'Item label',amount: '100.00',},],}// Check if ApplePay is availableif(ApplePay.canMakePayments){ApplePay.requestPayment(requestData).then((paymentData)=>{console.log(paymentData);// Simulate a request to the gatewaysetTimeout(()=>{// Show status to user ApplePay.SUCCESS || ApplePay.FAILUREApplePay.complete(ApplePay.SUCCESS).then(()=>{console.log('completed');// do something});},1000);});};

What is react-native ?

TLDR; — React Native (RN) creates cross-platform apps, more “native” than web-view apps made by Cordova / Ionic. But React Native is yet to release a stable (1.0.0_) version of the framework.

Безопасность

Stripe React Native SDK помогает собирать конфиденциальные данные, такие как номера кредитных карт, и безопасно принимать платежи, отправляя данные в API Stripe вместо того, чтобы передавать их через внутренний сервер.

Встроенный платежный интерфейс (бета)

SDK поддерживает встроенные платежные интерфейсы, предлагаемые Stripe. Эта функция находится в стадии бета-тестирования с поддержкой Apple Pay, Google Pay и пользовательских интерфейсов для оплаты картой. Тем не менее, в будущем планируется создать поддержку для большего количества вариантов оплаты. Вы можете прочитать об интерфейсах оплаты Stripe здесь.

В этих руководствах мы исследуем некоторые из перечисленных выше функций, создав и протестировав экран оплаты в нашем приложении React Native. Приступим к следующему разделу.

Готовый пользовательский интерфейс (пошаговый)

Эта функция представляет собой комбинацию всех шагов, связанных с принятием оплаты в Stripe с использованием данных кредитной карты. Для этой интеграции требуется конечная точка, которая взаимодействует с Stripe API с вашего сервера.

Настройка учетной записи stripe

Для каждого SDK требуются персональные ключи доступа, и Stripe не является исключением. Чтобы продолжить это руководство по React Native, мы должны создать учетную запись Stripe и получить наши личные ключи, чтобы принимать оплату.

Приложение react native stripe

Теперь, когда вы создали свою учетную запись Stripe и получили свой открытый ключ, давайте инициализируем новое приложение React Native и установим Stripe React Native SDK.

Перейдите в каталог разработки и вставьте команду ниже, чтобы установить новое приложение React Native:

После завершения установки перейдите в StripeReactNative через терминал и вставьте приведенный ниже код, чтобы установить пакет SDK Stripe React Native в ваше приложение:

SDK Stripe React Native имеет некоторые требования для поддержки Android и iOS. Вы можете сослаться на них здесь:

Android

  1. Android 5.0 (уровень API 21) и выше
  2. Плагин Android Gradle 4.x и выше

iOS

  1. Совместимость с приложениями, ориентированными на iOS 11 или выше.

Собственный интерфейс

SDK Stripe React Native поставляется с собственными экранами и элементами для безопасного приема платежей в Android и iOS.

Создание компонента карты

Для начала создайте новую папку с именем screens в корневом каталоге вашего приложения React Native.

Перейдите в папку и создайте новый файл с именем paymentScreen.js, затем вставьте код ниже:

import React, {useState} from "react";
import {
    CardField,
    CardFieldInput,
    useStripe,
  } from '@stripe/stripe-react-native';

  export default PaymentScreen = () => {
    const [card, setCard] = useState(CardFieldInput.Details | null);
    const {confirmPayment, handleCardAction} = useStripe()
    return(
        <CardField
      postalCodeEnabled={true}
      placeholder={{
        number: '4242 4242 4242 4242',
      }}
      cardStyle={{
        backgroundColor: '#FFFFFF',
        textColor: '#000000',
      }}
      style={{
        width: '100%',
        height: 50,
        marginVertical: 30,
      }}
      onCardChange={(cardDetails) => {
        setCard(cardDetails);
      }}
      onFocus={(focusedField) => {
        console.log('focusField', focusedField);
      }}
    />
    )
  }

Затем давайте импортируем paymentScreen.js в корень нашего проекта.

Откройте App.js и обновите его код, чтобы он выглядел так, как показано ниже:

Давайте запустим наше приложение, чтобы протестировать то, что мы создали. Запустите npx react-native run-ios, чтобы запустить сборку для iOS.

Скорее всего, вы столкнетесь с ошибкой undefined symbols for architecture x86_64, но не паникуйте! Чтобы исправить ошибку, выполните следующие действия:

Откройте свой проект Xcode и создайте новый файл Swift (File > New > File > Swift). Назовите файл как угодно (например, Fix.swift) и выберите создать заголовок моста, при появлении запроса от Xcode.

Запустите npx react-native run-iosеще раз, и ошибка должна быть исправлена. В случае успеха ваше приложение после загрузки должно выглядеть, как на скриншоте ниже:

Мы только что создали простой компонент карты, который отправляет данные карты непосредственно на сервер Stripe для проверки в реальном времени и впоследствии сохраняет состояние компонента.

Создание конечной точки

Чтобы настроить сервер для связи с Stripe из React Native, нам нужно инициализировать новое приложение node.js с install express body-parser и dotenv.

Создайте новую папку с именем server, перейдите в папку, запустите npm init -y и следуйте инструкциям, чтобы создать новое приложение Node. Затем запустите npm i express body-parser dotenv

Наконец, создайте файл server.js на корневом уровне папки сервера и вставьте в файл приведенный ниже код:

require("dotenv").config();
const express = require("express");
const app = express();
const { resolve } = require("path");
const stripe = require("stripe")(process.env.secret_key); // https://stripe.com/docs/keys#obtain-api-keys
app.use(express.static("."));
app.use(express.json());
// An endpoint for your checkout 
app.post("/checkout", async (req, res) => { 
  // Create or retrieve the Stripe Customer object associated with your user.
  let customer = await stripe.customers.create(); // This example just creates a new Customer every time

  // Create an ephemeral key for the Customer; this allows the app to display saved payment methods and save new ones
  const ephemeralKey = await stripe.ephemeralKeys.create(
    {customer: customer.id},
    {apiVersion: '2020-08-27'}
  );  

  // Create a PaymentIntent with the payment amount, currency, and customer
  const paymentIntent = await stripe.paymentIntents.create({
    amount: 973,
    currency: "usd",
    customer: customer.id
  });

  // Send the object keys to the client
  res.send({
    publishableKey: process.env.publishable_key, // https://stripe.com/docs/keys#obtain-api-keys
    paymentIntent: paymentIntent.client_secret,
    customer: customer.id,
    ephemeralKey: ephemeralKey.secret
  });
});

app.listen(process.env.PORT, () =>
  console.log(`Node server listening on port ${process.env.PORT}!`)
);

Не забудьте создать файл .env с кодом ниже:

Затем обновите paymentScreen.js с помощью кода ниже, чтобы добавить кнопку оформления заказа в приложение:

import React, { useState, useEffect } from "react";
import { StyleSheet, Button, View} from 'react-native';
import {
  CardField,
  CardFieldInput,
  useStripe,
} from '@stripe/stripe-react-native';

export default PaymentScreen = () => {
  const [card, setCard] = useState(CardFieldInput.Details | null);
  const { confirmPayment, handleCardAction } = useStripe()
  const API_URL = "http://localhost:8000";
  const { initPaymentSheet, presentPaymentSheet } = useStripe();
  const [loading, setLoading] = useState(false);

  const fetchPaymentSheetParams = async () => {
    const response = await fetch(`${API_URL}/checkout`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const { paymentIntent, ephemeralKey, customer } = await response.json();
    return {
      paymentIntent,
      ephemeralKey,
      customer,
    };
  };
  const initializePaymentSheet = async () => {
    const {
      paymentIntent,
      ephemeralKey,
      customer,
    } = await fetchPaymentSheetParams();
    const { error } = await initPaymentSheet({
      customerId: customer,
      customerEphemeralKeySecret: ephemeralKey,
      paymentIntentClientSecret: paymentIntent,
    });
    if (!error) {
      setLoading(true);
    }
  };
  const openPaymentSheet = async () => {
    const { error } = await presentPaymentSheet({ clientSecret });
    if (error) {
      Alert.alert(`Error code: ${error.code}`, error.message);
    } else {
      Alert.alert('Success', 'Your order is confirmed!');
    }
  };
  useEffect(() => {
    initializePaymentSheet();
  }, []);
  return (
    <View style={styles.container}>
      <CardField
        postalCodeEnabled={false}
        placeholder={{
          number: '4242 4242 4242 4242',
        }}
        cardStyle={{
          backgroundColor: '#FFFFFF',
          textColor: '#000000',
        }}
        style={{
          width: '100%',
          height: 50,
          marginVertical: 30,
        }}
        onCardChange={(cardDetails) => {
          setCard(cardDetails);
        }}
        onFocus={(focusedField) => {
          console.log('focusField', focusedField);
        }}
      />
        <Button
          style={styles.button}
          disabled={!loading}
          title="Checkout"
          color="#841584"
          onPress={openPaymentSheet}
        />
        </View>
  )
}
const styles = StyleSheet.create({
  container: {
     flex: 1,
     padding: 20,
     marginHorizontal: 10,
     marginVertical: 10,
  },
  button: {
     backgroundColor: '#00aeef',
     borderColor: 'red',
     borderWidth: 5,
     borderRadius: 15       
  }
})

Как видно выше, создайте отдельный проект node.js и настройте сервер с портом 8000. Из React Native отправьте запрос в конечную точку /checkout на сервере. Как только запрос будет выполнен успешно, initializePaymentSheet будет вызван с помощью хука useEffect.

Во время этого процесса кнопка остается неактивной до тех пор, пока не будет получен ответ от серверной части. Обратите внимание, что ваш бэкэнд-сервер должен быть запущен и работать до тех пор, пока вы намереваетесь обмениваться данными с ним.

На этом этапе ваше приложение должно выглядеть примерно так, как показано на скриншоте ниже:

Создание платежного экрана

Теперь, когда SDK успешно установлен, приступим к созданию нашего первого экрана оплаты.

Установка с ios

Установить Stripe React Native SDK в iOS немного сложнее, чем в Android.

Чтобы избежать ошибок после установки пакета через npm, откройте StripeReactNative.xcworkspace в XCode и установите цель развертывания на iOS 11.0. Пример см. на скриншоте ниже:

Запустите свой проект из Xcode, чтобы убедиться, что все изменения применены, затем перейдите в папку iOS. Откройте podfile, обновите platform :ios, ‘10.0’ до platform :ios, ’11.

Далее, давайте избавимся от стандартного собственного кода React из App.js. Обновите файл App.js с кодом ниже:

Если вы запустите приложение, вы должны увидеть пустой экран, аналогичный показанному ниже:

Initializegooglepay

Android Only

Optional: Used to enable Google Pay in an Android app. Initialize React Native plugin for google pay.
This is a method called only once when React Native app is being initialized on an Android device.

Заключение

Stripe React Native SDK от Stripe очень легко реализовать. Благодаря поддержке готовых пользовательских интерфейсов (включая планы по будущей поддержке большего количества готовых пользовательских интерфейсов) и вариантам оплаты, он становится фаворитом разработчиков.

Conclusion

In this blog we learnt how to implement Stripe Payment in a React Native app. I know it is a long post with a lot to understand. Let me repeat the gist of the post — 

Stripe payment consists of two parts — front-end (tokenization) and back-end (actual payment request). The Stripe payment integration will follow this pictorial flow

Stripe Ionic 4 integration flow

Complete source code of this tutorial is available in the RNStripe Github repository.

Stay tuned for more React Native blogs !

Step 2: initialize apple pay and verify apple pay support

Add code to initialize Apple Pay in your application State class.

  • Replace REPLACE_WITH_APPLE_PAY_MERCHANT_ID in this example with a valid apple pay merchant ID.

Initializeapplepay

iOS Only

Initializes the In-App Payments React Native plugin for Apple Pay.

This is a method called only once when React Native app is being initialized on an iOS device.
Call this method only on an iOS device and when your app is intended to support Apple Pay.

ParameterTypeDescription
applePayMerchantIdStringRegistered Apple Pay merchant ID

Initializing the payment request

To initialize a Payment Request, you’ll need to provide PaymentMethodData and PaymentDetails.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *