peach-pay-react-native
v1.0.2
Published
A React Native library for Peach Payments
Downloads
1
Maintainers
Readme
Peach Payments Mobile for React Native
Peach Payments Mobile component or React Native (iOS and Android) Peach Payments is a South African payment gateway. It currently powers businesses in South Africa and Mauritius and will soon be launching services in Kenya, Nigeria and more countries in Africa.
This React Native component bridges the Peach Payments Mobile SDk, specifically the "SDK & Your Own UI" functions. Before using this component, first read through Peach Payment's documentation, especially their "Set Up Your Server"" doc. You will need to expose two APIs on your backend for your app to communicate with.
Setup
Installation
Installing (React Native >= 0.60.0)
Install react-native-peach-mobile
(latest):
yarn add react-native-peach-mobile react-native-webview --save
or
npm install react-native-peach-mobile react-native-webview --save
Go to your ios folder and run:
pod install
Installing (React Native == 0.59.x)
Install react-native-peach-mobile
(latest):
yarn add react-native-peach-mobile --save
or
npm install react-native-peach-mobile
Use react-native link
to add the package to your project:
react-native link react-native-peach-mobile
Integrating into Your App
The following things need to be setup for the package to work. If you get stuck, check the Example App's files.
iOS
Add the following to AppDelegate.m
, replacing "com.example.app.payments" on line two with your app's bundle ID plus .payments
:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
if ([url.scheme localizedCaseInsensitiveCompare:@"com.example.app.payments"] == NSOrderedSame) {
[NSNotificationCenter.defaultCenter postNotificationName:@"AsyncPaymentCompletedNotificationKey" object:nil];
return true;
}
return false;
}
Add the following to Info.plist
again, replacing "com.example.app.payments" on line three with your app's bundle ID plus .payments
:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>com.example.app.payments</string>
</array>
The last thing to set for the 3D secure to work is the URL type in the Info tab in XCode(also replacing "com.example.app.payments" on line three with your app's bundle ID plus .payments
):
The iOS is written in Swift, it is therefore necessary to create a Swift Bridging Header (If you don't have one already).
Add a new file to Xcode (File > New > File), then select “Swift File”. Name your file RNPlaceholder
. You should get an alert box asking "Would you like configure an Objective-C bridging header?". Select 'Create Bridging Header'.
Android
To configure the external linking in Android for the 3D secure redirect, you need to create a new intent in the manifest.
- Set launchMode of MainActivity to singleTask in order to receive intent on existing MainActivity.
- Add the new intent-filter inside the MainActivity entry with a VIEW type action:
Here is an example of what your AndroidManifest.xml
should look like: (remember to replace "com.example.app.payments" on line two with your app's package name plus .payments
:
...
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="com.example.app.payments"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
...
Add the following to your app's MainActivity.java
to handle the intent in the MainActivity
:
//Add this import to the top of the file
import android.content.Intent;
//Add this inside the class
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
Your minSdkVersion to use this package should be 17.
You can change that in the android/build.gradle
file
buildscript {
ext {
...
minSdkVersion = 17
}
}
If you get this error when building 'The number of method references in a .dex file cannot exceed 64K.'.
Just add these lines in the app/build.gradle
file
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
...
implementation 'com.android.support:multidex:1.0.3'
}
Usage
A complete working example can be found in the /ExampleApp directory.
Since this package bridges the functionality of the Peach Payments Mobile SDK's custom UI functionality it follows the same four steps for accepting payments:
- Preparing checkout (configure with amount, currency and other information),
- Collecting shopper payment details,
- Creating and submitting transaction,
- Requesting payment result.
Follow the next few steps to start accepting payments in your app:
- Import react-native-peach-mobile:
import PeachMobile from 'react-native-peach-mobile';
- Add the PeachMobile component inside your render function and create a ref to the component:
render() {
const { cardHolder, cardNumber, cardExpiryYear, cardExpiryMonth, cardCVV } = this.state;
return (
<PeachMobile
mode="test"
urlScheme="com.example.app.payments"
cardHolder={cardHolder}
cardNumber={cardNumber}
cardExpiryYear={cardExpiryYear}
cardExpiryMonth={cardExpiryMonth}
cardCVV={cardCVV}
checkoutID={checkoutID}
ref={this.setPeachMobileRef}
/>
);
}
setPeachMobileRef(ref) {
this.peachMobile = ref;
}
The URL Scheme should be the same as you set when integrating the package into Your app, i.e your bundle ID plus .payments
.
For all props that can be passed to the component and their descriptions see Available Props
(It does not really matter where the PeachMobile component is placed within your JSX. The PeachMobile component renders a modal containing the 3D secure webview, the modal will be displayed above the current screen.)
- Get checkout ID:
let checkoutIdResponse = await PeachMobile.getCheckoutId(
transaction.url + '/v1/checkouts',
transaction.amount,
transaction.currency,
transaction.paymentType,
{
entityId: '8a8294174e735d0c014e78cf26461790',
notificationUrl: 'https://en962llz1kivw.x.pipedream.net'
},
{ Authorization: `Bearer ${authToken}` },
transaction.testMode
);
this.setState({checkoutID: checkoutIdResponse});
- Submit the transaction:
await this.peachMobile.submitTransaction();
- Get the payment status:
let response = await PeachMobile.getPaymentStatus(
transaction.url,
null,
{entityId: '8a8294174e735d0c014e78cf26461790'},
{ Authorization: `Bearer ${authToken}` }
);
const successCodesPattern = /^(000\.000\.|000\.100\.1|000\.[36])/;
if (response.data.result.code && successCodesPattern.test(response.data.result.code)) {
Alert.alert('Transaction Successful', 'The transaction was successful.');
} else {
Alert.alert('Transaction Unsuccessful', `Transaction was unsuccessful. ${response.data.result.description}`);
}
Available Props
| Name | Type | Default | Description |
| ------------------- | ---------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| mode | string | 'test' | The mode SDK payment provider should operate in. Can be test
or live
. |
| urlScheme | string | Required | The scheme that is used when redirecting after 3D secure has completed. Should be the bundle ID of the app play .payments
|
| modalHeader | node | | The element that will be rendered above the webview inside the modal. |
| modalFooter | node | null | The element that will be rendered below the webview inside the modal. |
| webviewStyle | object | null | The styles for the webview. This prop is directly passed to the WebView
component's style prop. |
| modalStyle | object | null | The styles for the modal. This prop is directly passed to the Modal
component's style prop. |
| modalContainerStyle | object | null | The styles for the view that wraps the modals content, including the modalHeader, webview and modalFooter. |
| checkoutID | string | Conditional* | The checkout ID received from your server. |
| paymentBrand | string | null | The card brand. E.g Visa, MasterCard, etc. |
| cardHolder | string | Conditional* | The name of the card holder appearing on the card. |
| cardNumber | string | Conditional* | The card number appearing on the card. |
| cardExpiryMonth | string | Conditional* | The card expiry month. |
| cardExpiryYear | string | Conditional* | The card expiry year. |
| cardCVV | string | Conditional* | The three or four digit CVV code of the card. |
*All the fields marked Conditional* are not required if you pass the submitTransaction()
function a transaction object.
Available Methods
getCheckoutId()
static getCheckoutId(url: string, amount: string, currency: string, paymentType: string, otherParams: object, requestHeaders: object, testMode: string)
Request the checkout ID from your server. You don't need to use this function. You can write your own function for making the request for the checkout ID from your server and still normally pass it to the PeachMobile
component. Returns a axios request promise.
Parameters:
| Name | Type | Required | Description | | -------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | url | string | Yes | The url the request for the checkout ID should be made too. | | amount | string | Yes | The amount that should be charged to the users card. | | currency | string | Yes | The currency the amount should be charged in. | | paymentType | string | Yes | The payment type for the request. Check Peach Payments API Reference for all payment types and descriptions. | | otherParams | object | No | Any other params that needs to be passed with the call. | | requestHeaders | object | No | Request headers for the network call. | | testMode | string | No | The testMode for the checkout. Can be 'EXTERNAL' or 'INTERNAL'. Check Peach Payments API Reference for more information on testMode. |
createTransaction()
static createTransaction(checkoutID: string, paymentBrand: string, cardHolder: string, cardNumber: string, cardExpiryMonth: string, cardExpiryYear: string, cardCVV: string)
Validate the card parameters and create a transaction object. Returns a promise that when resolves will return a transaction object. You can use this function to create a transaction that can be passed to the submitTransaction
or submitRegistration
functions.
Parameters:
| Name | Type | Required | Description | | --------------- | ------ | -------- | ---------------------------------------------------| | checkoutID | string | Yes | The checkout ID received from your server. | | paymentBrand | string | No | The card brand. E.g Visa, MasterCard, etc. | | cardHolder | string | Yes | The name of the card holder appearing on the card. | | cardNumber | string | Yes | The card number appearing on the card. | | cardExpiryMonth | string | Yes | The card expiry month. | | cardExpiryYear | string | Yes | The card expiry year. | | cardCVV | string | Yes | The three or four digit CVV code of the card. |
createTransactionWithToken()
static createTransactionWithToken(checkoutID: string, paymentBrand: string, tokenID: string, cardCVV: string)
Create a transaction object with a tokenized card. Returns a promise that when resolves will return a transaction object. You can use this function to create a transaction that can be passed to the submitTransaction
function.
Parameters:
| Name | Type | Required | Description | | --------------- | ------ | -------- | ---------------------------------------------------| | checkoutID | string | Yes | The checkout ID received from your server. | | paymentBrand | string | No | The card brand. E.g Visa, MasterCard, etc. | | tokenID | string | Yes | The tokenID of the tokenized card. | | cardCVV | string | No | The three or four digit CVV code of the card. |
submitTransaction()
static submitTransaction(transaction: TransactionObject, mode: TransactionMode)
Submit the transaction to peach payments. Returns a promise that will resolve to true if the transaction was successfully submitted or will reject if there was an error. A 3D secure modal will automatically open if 3D secure is required, once the user has submitted the 3D secure form the modal will again automatically close and the promise will resolve.
Parameters:
| Name | Type | Required | Description |
| --------------- | ----------------- | --------- | ------------------------------------------------------------------|
| transaction | TransactionObject | Yes | Transaction object created by the createTransaction()
function. |
| mode | TransactionMode | Yes | Transaction mode, 'live' or 'test'. |
submitRegistration()
static submitTransaction(transaction: TransactionObject, mode: TransactionMode)
Submit the card registration to peach payments. Returns a promise that will resolve to true if the transaction was successfully submitted or will reject if there was an error. A 3D secure modal will automatically open if 3D secure is required, once the user has submitted the 3D secure form the modal will again automatically close and the promise will resolve.
Parameters:
| Name | Type | Required | Description |
| --------------- | ----------------- | --------- | ------------------------------------------------------------------|
| transaction | TransactionObject | Yes | Transaction object created by the createTransaction()
function. |
| mode | TransactionMode | Yes | Transaction mode, 'live' or 'test'. |
getResourcePath()
static getResourcePath()
Get the resource path after the transaction has been submitted. Will return a promise that resolves to the resource path string. Useful when you are using your own function to check the transaction status and require the resource path.
getPaymentStatus()
static getPaymentStatus(url: string, resourcePath: string, otherParams: object, requestHeaders: object)
Get the status of the payment after the transaction has been submitted. Will return a axios request promise. You don't need to use this function. You can write your own function for requesting the transaction status from your server.
Paramaters:
| Name | Type | Required | Description |
| -------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| url | string | Yes | The url the request for the transaction status should be made too. |
| resourcePath | string | No | The resource path requested from the SDK. If this is not passed, the function will fetch it from the SDK using the getPaymentStatus()
function. |
| otherParams | object | No | Any other params that needs to be passed with the call. |
| requestHeaders | object | No | Request headers for the network call. |
Available Modal Props
Take a look at react-native-modal to see all the available props to customise the 3D secure modal. All the props of the Modal are directly available through the PeachMobile
component except the isVisible
prop. The isVisible
prop is controlled by the package to show and hide the 3D secure modal automatically.