Skip to content

Latest commit

 

History

History
534 lines (425 loc) · 12.8 KB

tipsi-stripe-migration-guide.md

File metadata and controls

534 lines (425 loc) · 12.8 KB

Tipsi-stripe migration guide

Introduction

stripe-react-native is a official replacement for tipsi-stripe, provides bunch of functionalities which allows you to build delightful payment experiences using React Native. In addition to those already available in tipsi-stripe we also offer features like Pre-built payments UI, Simplified Security and more...

Installation

IMPORTANT: If migrating from tipsi-stripe to stripe-react-native, please be sure to first remove all tipsi-stripe dependencies from your project. tipsi-stripe uses older versions of stripe-android and stripe-ios which aren't compatible with stripe-react-native.

Usage

stripe-react-native library provides two initializing ways, in order to do this you can use either StripeProvider component or initStripe method. Please refer to documentation for more details.

before:

stripe.setOptions({
  publishableKey: 'PUBLISHABLE_KEY',
  merchantId: 'MERCHANT_ID', // Optional
  androidPayMode: 'test', // Android only
});

after: initStripe or StripeProvider

import { StripeProvider } from '@stripe/stripe-react-native';

// ...

<StripeProvider
  publishableKey="publishable_key"
  merchantIdentifier="merchant.identifier"
 >
  // Your app code here
</StripeProvider>

or

import { initStripe } from '@stripe/stripe-react-native';

// ...

initStripe({
  publishableKey: 'publishable_key'
  merchantIdentifier: 'merchant.identifier',
});

Class vs functional components

All of the stripe functions can be imported directly from @stripe/stripe-react-native so that you can use them both with class and functional components. However, you are also able to access them via dedicated hooks. For instance you can use useConfirmPayment hook which apart from confirmPayment method provides also loading state so you don't need to handle it manually. Moreover, there is also the main useStripe hook which provides all of the stripe methods. examples:

import { useConfirmPayment } from '@stripe/stripe-react-native';

const { confirmPayment, loading } = useConfirmPayment();

// await confirmPayment(...)
import { useStripe } from '@stripe/stripe-react-native';

const { confirmPayment } = useStripe();

// await confirmPayment(...)
import { confirmPayment } from '@stripe/stripe-react-native';

// await confirmPayment(...)

Card components

Use below components on your payment screen to securely collect card details from your customers.

before:

<PaymentCardTextField
	style={styles.field}
	cursorColor={...}
	textErrorColor={...}
	placeholderColor={...}
	numberPlaceholder={...}
	expirationPlaceholder={...}
	cvcPlaceholder={...}
	disabled={false}
	onParamsChange={(valid, params) => {
		console.log(`
			Valid: ${valid}
			Number: ${params.number || '-'}
			Month: ${params.expMonth || '-'}
			Year: ${params.expYear || '-'}
			CVC: ${params.cvc || '-'}
`		);
	}}
/>

after: CardField

<CardField
  postalCodeEnabled={false}
  autofocus
  placeholders={{
    number: '4242 4242 4242 4242',
    postalCode: '12345',
    cvc: 'CVC',
    expiration: 'MM|YY',
  }}
  onCardChange={(cardDetails) => {
    console.log('cardDetails', cardDetails);
  }}
  onFocus={(focusedField) => {
    console.log('focusField', focusedField);
  }}
  cardStyle={{
    borderWidth: 1,
    backgroundColor: '#FFFFFF',
    borderColor: '#000000',
    borderRadius: 8,
    fontSize: 14,
    placeholderColor: '#999999',
  }}
  style={{ width: '100%', height: 200 }}
/>

or CardForm

<CardForm
  autofocus
  cardStyle={{
    backgroundColor: '#FFFFFF',
  }}
  style={{ width: '100%', height: 350 }}
  onFormComplete={(cardDetails) => {
    setComplete(cardDetails.complete);
  }}
/>

PaymentIntent API

Please note that for PCI compliance reasons all of the sensitive data is sent to the specific methods under the hood and you don’t need to hand it over on your own. This means that in order to proceed any Card payment, you have to collect the data using either CardField or CardForm component provided by stripe-react-native library. In this way the personal data is secure, as it is kept confidential from developers.

createPaymentMethod()

Creating a payment method using card details:

before:

try {
  const paymentMethod = await stripe.createPaymentMethod({
    card: {
      number: '4000002500003155',
      cvc: '123',
      expMonth: 11,
      expYear: 2020,
    },
  });
} catch (e) {
  // Handle error
}

after: createPaymentMethod

// ...
const { paymentMethod, error } = await createPaymentMethod({
  paymentMethodType: 'Card',
  paymentMethodData: {
    billingDetails,
  }, // optional
});

return (
  <CardField style={{ width: '100%', height: 100 }} postalCodeEnabled={true} />
);

Confirm payment Intent - Manual

If your payment requires action (i.e. status == 'requires_action'), you have to call this specific method in order to launch an activity where the user can authenticate the payment. Call this method if you are using manual confirmation.

before:

await stripe.authenticatePaymentIntent({ clientSecret: 'client_secret' });

after: handleNextAction

const { error, paymentIntent } = await handleNextAction('client_secret');

Confirm payment Intent - Automatic

Call this method if you are using automatic confirmation.

before:

const confirmPaymentResult = await stripe.confirmPaymentIntent({
	clientSecret: 'client_secret',
	paymentMethod: {
		billingDetails: {...},
		card: {
			cvc: '242',
			expMonth: 11,
			expYear: 2040,
			number: '4000002500003155',
		}
	});

after: confirmPayment

// ...
const { error, paymentIntent } = await confirmPayment('client_secret', {
	paymentMethodType:  'Card',
  paymentMethodData: {
	  billingDetails: {...},
  }
});

// ...

return (
 <CardField
    style={{ width: '100%', height: 100 }}
    postalCodeEnabled={true}
  />
);

Set up future payments

Use this integration to set up recurring payments or to create one-time payments with a final amount determined later, often after the customer receives your service.

before:

try {
  const result = await stripe.confirmSetupIntent({ clientSecret: '...' });
} catch (e) {
  // handle exception here
}

after: confirmSetupIntent

const { error, setupIntent } = await confirmSetupIntent(clientSecret, {
  type: 'Card',
  billingDetails,
});

// ...

return (
  <CardField style={{ width: '100%', height: 100 }} postalCodeEnabled={true} />
);

Apple Pay

deviceSupportsNativePay()

Before displaying Apple Pay as a payment option in your app, determine if the user’s device supports Apple Pay and that they have a card added to their wallet. In order to this stripe-react-native provides isApplePaySupported boolean value from useApplePay hook.

NOTE: The iOS Simulator always returns true.

before:

import stripe from 'tipsi-stripe'
// ...
const isApplePaySupported = await stripe.deviceSupportsNativePay()
// ...
return (
	// ...
	{isApplePaySupported && (
		<Button onPress={pay} />
	)}
);

after: isApplePaySupported

import { useApplePay } from '@stripe/stripe-react-native'
// ...
const { isApplePaySupported } = useApplePay()
// ...
return (
	// ...
	{isApplePaySupported && (
		<Button onPress={pay} />
	)}
);

if your application doesn't use functional components, as an alternative you can import isApplePaySupported method directly.

import { isApplePaySupported } from '@stripe/stripe-react-native';
// ...
const isSupported = isApplePaySupported();
// ...

paymentRequestWithNativePay()

Next, initialize the payment. Please refer to the documentation for all available properties.

before:

const items = [
  {
    label: 'Whisky',
    amount: '50.00',
  },
];

const shippingMethods = [
  {
    id: 'fedex',
    label: 'FedEX',
    detail: 'Test @ 10',
    amount: '10.00',
  },
];

const options = {
  requiredBillingAddressFields: ['all'],
  requiredShippingAddressFields: ['phone', 'postal_address'],
  shippingMethods,
};

const token = await stripe.paymentRequestWithNativePay(items, options);

after: presentApplePay

const shippingMethods = [
  {
    identifier: 'standard',
    detail: 'Arrives by June 29',
    label: 'Standard Shipping',
    amount: '3.21',
  },
];

const items = [
  { label: 'Subtotal', amount: '12.75', type: 'final' },
  { label: 'Shipping', amount: '0.00', type: 'pending' },
  { label: 'Total', amount: '12.75', type: 'pending' }, // Last item in array needs to reflect the total.
];

const { error, paymentMethod } = await presentApplePay({
  cartItems: items,
  country: 'US',
  currency: 'USD',
  shippingMethods,
  requiredShippingAddressFields: [
    'emailAddress',
    'phoneNumber',
    'postalAddress',
    'name',
  ],
  requiredBillingContactFields: ['phoneNumber', 'name'],
  jcbEnabled: true,
});

completeNativePayRequest()

Call this method to complete the payment.

before:

try {
  stripe.completeNativePayRequest();
} catch (error) {
  // ...
}

after: confirmApplePayPayment

const { error } = await confirmApplePayPayment('client_secret');

GooglePay

paymentRequestWithNativePay()

before:

const token = await stripe.paymentRequestWithNativePay({
  total_price: '100.00',
  currency_code: 'USD',
  shipping_address_required: true,
  phone_number_required: true,
  shipping_countries: ['US', 'CA'],
  line_items: [
    {
      currency_code: 'USD',
      description: 'Whisky',
      total_price: '50.00',
      unit_price: '50.00',
      quantity: '1',
    },
  ],
});

after: initGooglePay and presentGooglePay

const { error } = await initGooglePay({
    merchantName: 'Widget Store'
    countryCode: 'US',
    billingAddressConfig: {
      format: 'FULL',
      isPhoneNumberRequired: true,
      isRequired: false,
    },
    existingPaymentMethodRequired: false,
    isEmailRequired: true,
});
if (error) {
    // handle error
    return;
}
const { error: presentError } = await presentGooglePay({
    clientSecret,
    forSetupIntent: true,
    currencyCode: 'USD',
});

As against to tipsi-stripe, stripe-react-native provide separate API for GooglePay, please refer to the documentation for more details.

Create a token

createTokenWithCard()

Use this method to convert information collected by card components into a single-use Token that you safely pass to your server to use in an API call.

before:

const params = {
  number: '4242424242424242',
  expMonth: 11,
  expYear: 17,
  cvc: '223',
  name: 'Test User',
  currency: 'usd',
  addressLine1: '123 Test Street',
  addressLine2: 'Apt. 5',
  addressCity: 'Test City',
  addressState: 'Test State',
  addressCountry: 'Test Country',
  addressZip: '55555',
};
const token = await stripe.createTokenWithCard(params);

after: createToken

const { createToken } = useStripe()
// ...
const { token, error } = await createToken({
	type: 'Card'
	address: {
		country: 'US',
		// ...
	},
	name: 'card_name'
});
// ...
return (
 <CardField
    style={{ width: '100%', height: 100 }}
  />
);