npm package: @paytabs/react-native-paytabs
Description: Paytabs React-Native Library
Author: Muhammad Alkady
Latest version: 2.8.11

# react-native-paytabs

![Version](https://img.shields.io/badge/React%20Native%20Paytabs-v2.8.11-green)

React native paytabs library is a wrapper for the native PayTabs Android and iOS SDKs, It helps you
integrate with PayTabs seamlessly.

Library Support:

* [x] iOS
* [x] Android
* [x] Android 16 (SDK 36) with Edge-to-Edge support

Library Version:

* [x] React Version: 18.1.0
* [x] React-Native Version: 0.70.6
* [x] PayTabs Android SDK: 6.8.8
* [x] Target SDK: 36 (Android 16)

# Installation

```sh
$ npm install @paytabs/react-native-paytabs@2.8.11 --save
```

### Expo

```sh
expo install @paytabs/react-native-paytabs
```

### Follow the below steps to complete the installation

* Android
  * Add `packagingOptions` to module `build.gradle` file

  ```
  android {
    ...
    packagingOptions {
          pickFirst '**/*.so'
      }
  }
  ```

  **Android 16 Edge-to-Edge Support:**

  This library now supports Android 16 (SDK 36) with mandatory edge-to-edge enforcement. The library has been updated to use:
  * PayTabs SDK 6.8.8 with Android 16 compatible dependencies
  * androidx.activity 1.13.0 for edge-to-edge compatibility
  * compileSdk 36 and targetSdk 36

  If you experience any edge-to-edge related issues, ensure your app's `build.gradle` uses at least:
  ```gradle
  compileSdkVersion 36
  targetSdkVersion 36
  ```

* iOS

  * Add `libswiftWebKit.tbd` to your **Link Binary With Libraries**
  * Navigate to the iOS folder and run the following command:

  ```
  pod install
  ```

## Usage

Import `@paytabs/react-native-paytabs`

```javascript
import {RNPaymentSDKLibrary, PaymentSDKConfiguration, PaymentSDKBillingDetails, PaymentSDKTheme, PaymentSDKConstants, PaymentSDKSavedCardInfo} from '@paytabs/react-native-paytabs';
```

### Pay with Card

1. Configure the billing & shipping info, the shipping info is optional

```javascript
let billingDetails = new PaymentSDKBillingDetails(name= "John Smith",
                                  email= "email@test.com",
                                  phone= "+2011111111",
                                  addressLine= "address line",
                                  city= "Dubai",
                                  state= "Dubai",
                                  countryCode= "ae", // ISO alpha 2
                                  zip= "1234")

let shippingDetails = new PaymentSDKShippingDetails(name= "John Smith",
                                  email= "email@test.com",
                                  phone= "+2011111111",
                                  addressLine= "address line",
                                  city= "Dubai",
                                  state= "Dubai",
                                  countryCode= "ae", // ISO alpha 2
                                  zip= "1234")

```

2. Create object of `PaymentSDKConfiguration` and fill it with your credentials and payment details.

```javascript

let configuration = new PaymentSDKConfiguration();
    configuration.profileID = "*your profile id*"
    configuration.serverKey= "*server key*"
    configuration.clientKey = "*client key*"
    configuration.cartID = "545454"
    configuration.currency = "AED"
    configuration.cartDescription = "Flowers"
    configuration.merchantCountryCode = "ae"
    configuration.merchantName = "Flowers Store"
    configuration.amount = 20
    configuration.screenTitle = "Pay with Card"
    configuration.billingDetails = billingDetails
	 configuration.forceShippingInfo = false
```

Options to show billing and shipping info

```javascript

	configuration.showBillingInfo = true
	configuration.showShippingInfo = true

```

Options to set expiry timeout for the card payment screen

```javascript

/** To establish a timeout of 2 minutes.
 * Set to zero to deactivate the timeout feature.
 * Note that the expiryTime cannot be set to less than 60 seconds.
 * */
configuration.expiryTime = 120;

```

You can dismiss the payment screen if there is no transaction in progress.

```javascript

RNPaymentSDKLibrary.cancelPayment()

```

# 1- Pay with card

Start payment by calling `startCardPayment` method and handle the transaction details

```javascript

RNPaymentSDKLibrary.startCardPayment(JSON.stringify(configuration)).then( result => {
      if(result["PaymentDetails"] != null) { // Handle transaction details
        let paymentDetails = result["PaymentDetails"]
        console.log(paymentDetails)
      } else if(result["Event"] == "CancelPayment") { // Handle events
        console.log("Cancel Payment Event")
      }
     }, function(error) { // Handle error
      console.log(error)
     });

```

<img width="191" alt="card" src="https://user-images.githubusercontent.com/17829232/188835902-c50f41d1-5e3d-4d4c-a49a-e75b81480b75.png">

# 2- Pay with Token

Start payment by calling `startTokenizedCardPayment` method and handle the transaction details

```javascript

RNPaymentSDKLibrary.startTokenizedCardPayment(JSON.stringify(configuration),
"Token",
"TransactionReference"
).then( result => {
      if(result["PaymentDetails"] != null) { // Handle transaction details
        let paymentDetails = result["PaymentDetails"]
        console.log(paymentDetails)
      } else if(result["Event"] == "CancelPayment") { // Handle events
        console.log("Cancel Payment Event")
      }
     }, function(error) { // Handle error
      console.log(error)
     });

```

# 3- Pay with 3DS Secured Token

Start payment by calling `start3DSecureTokenizedCardPayment` method and handle the transaction
details

```javascript
let cardInfo = new PaymentSDKSavedCardInfo("Card mask", "cardType")
RNPaymentSDKLibrary.start3DSecureTokenizedCardPayment(
  JSON.stringify(configuration),
  JSON.stringify(cardInfo),
  "Token"
  ).then( result => {
      if(result["PaymentDetails"] != null) { // Handle transaction details
        let paymentDetails = result["PaymentDetails"]
        console.log(paymentDetails)
      } else if(result["Event"] == "CancelPayment") { // Handle events
        console.log("Cancel Payment Event")
      }
     }, function(error) { // Handle error
      console.log(error)
     });

```

<img width="197" alt="rec 3ds" src="https://user-images.githubusercontent.com/17829232/188836295-d8d48978-a80f-40d3-bda3-439423fcdec0.png">

# 4- Pay with saved card

Start payment by calling `startPaymentWithSavedCards` method and handle the transaction details

```javascript

RNPaymentSDKLibrary.startPaymentWithSavedCards(JSON.stringify(configuration),
support3DsBool).then( result => {
      if(result["PaymentDetails"] != null) { // Handle transaction details
        let paymentDetails = result["PaymentDetails"]
        console.log(paymentDetails)
      } else if(result["Event"] == "CancelPayment") { // Handle events
        console.log("Cancel Payment Event")
      }
     }, function(error) { // Handle error
      console.log(error)
     });

```

<img width="197" alt="rec 3ds" src="https://user-images.githubusercontent.com/17829232/190152848-bfc83f8c-1a4b-4a55-99ec-af3c22a3de66.png">

### Pay with Apple Pay

1. Follow the guide [Steps to configure Apple Pay][applepayguide] to learn how to configure ApplePay
   with PayTabs.

2. Do the steps 1 and 2 from **Pay with Card** although you can ignore Billing & Shipping details
   and Apple Pay will handle it, also you must pass the **merchant name** and **merchant identifier
   **.

```javascript


let configuration = new PaymentSDKConfiguration();
    configuration.profileID = "*your profile id*"
    configuration.serverKey= "*server key*"
    configuration.clientKey = "*client key*"
    configuration.cartID = "545454"
    configuration.currency = "AED"
    configuration.cartDescription = "Flowers"
    configuration.merchantCountryCode = "ae"
    configuration.merchantName = "Flowers Store"
    configuration.amount = 20
    configuration.screenTitle = "Pay with Card"
    configuration.merchantIdentifier = "merchant.com.bundleID"

//ignore this if you want to use default Networks

const selectedNetworks = [PaymentSDKNetworks.DISCOVER];
configuration.paymentNetworks = selectedNetworks;

```

3. To simplify ApplePay validation on all user's billing info, pass **simplifyApplePayValidation**
   parameter in the configuration with **true**.

```javascript

configuration.simplifyApplePayValidation = true

```

4. Call `startApplePayPayment` to start payment

```javascript
RNPaymentSDKLibrary.startApplePayPayment(JSON.stringify(configuration)).then( result => {
        if(result["PaymentDetails"] != null) { // Handle transaction details
          let paymentDetails = result["PaymentDetails"]
          console.log(paymentDetails)
        } else if(result["Event"] == "CancelPayment") { // Handle events
          console.log("Cancel Payment Event")
        }
     }, function(error) { // handle errors
      console.log(error)
     });
```

### Pay with Samsung Pay

Pass Samsung Pay token to the configuration and call `startCardPayment`

```javascript
configuration.samsungToken = "token"
```

### Pay with Alternative Payment Methods

It becomes easy to integrate with other payment methods in your region like STCPay, OmanNet, KNet,
Valu, Fawry, UnionPay, and Meeza, to serve a large sector of customers.

1. Do the steps 1 and 2 from **Pay with Card**.

2. Choose one or more of the payment methods you want to support.

```javascript
configuration.alternativePaymentMethods = [PaymentSDKConstants.AlternativePaymentMethod.stcPay]
```

3. Start payment by calling `startAlternativePaymentMethod` method and handle the transaction
   details

```javascript

RNPaymentSDKLibrary.startAlternativePaymentMethod(JSON.stringify(configuration)).then( result => {
      if(result["PaymentDetails"] != null) { // Handle transaction details
        let paymentDetails = result["PaymentDetails"]
        console.log(paymentDetails)
      } else if(result["Event"] == "CancelPayment") { // Handle events
        console.log("Cancel Payment Event")
      }
     }, function(error) { // Handle error
      console.log(error)
     });

```

## Tokenisation

Follow the below instructions to enable tokenisation feature.

1. Request token

```javascript
configuration.tokeniseType = PaymentSDKConstants.TokeniseType.userOptional // read more about the tokeniseType in the enums section
configuration.tokenFormat = PaymentSDKConstants.TokeniseFormat.hex32 // read more about the tokenFormat in the enums section

```

After passing those parameters, you will receive a token and transaction reference in the result
callback, save them for future usage.

2. Pass the token & transaction reference

```javascript
configuration.token = token
configuration.transactionReference = transactionreference
```

## Enums

Those enums will help you in customizing your configuration.

* Tokenise types

The default type is none

```javascript
TokeniseType = {
"none":"none", // tokenise is off
"merchantMandatory":"merchantMandatory", // tokenise is forced
"userMandatory":"userMandatory", // tokenise is forced as per user approval
"userOptional":"userOptional", // tokenise if optional as per user approval, default is off.
"userOptionalDefaultOn": "userOptionalDefaultOn" // tokenise if optional as per user approval, default is on.
};
```

```javascript
configuration.tokeniseType = PaymentSDKConstants.TokeniseType.userOptional
```

* Token formats

The default format is hex32

```javascript
TokeniseFormat = {"none":"1",
"hex32": "2",
"alphaNum20": "3",
"digit22": "3",
"digit16": "5",
"alphaNum32": "6"
};
```

```javascript
configuration.tokenFormat = PaymentSDKConstants.TokeniseFormat.hex32
```

* Transaction types

The default type is sale

```javascript
TransactionType = {"sale":"sale",
"authorize": "auth"};
```

```javascript
configuration.transactionType = PaymentSDKConstants.TransactionType.sale
```

* Alternative payment methods

```javascript
AlternativePaymentMethod = {"unionPay":"unionpay", "stcPay":"stcpay", "valu": "valu", "meezaQR": "meezaqr", "omannet": "omannet", "knetCredit": "knetcredit", "knetDebit": "knetdebit", "fawry": "fawry", "aman": "aman", "urpay": "urpay", "souhoola": "souhoola", "tabby": "tabby", "tru": "tru", "tamara": "tamara", "forsa": "forsa"};
```

```javascript
configuration.alternativePaymentMethods = [PaymentSDKConstants.AlternativePaymentMethod.stcPay,]
```

## Discounts

* To apply discounts on the transaction, you can pass the discount amount and the discount type.

```javascript
let cardDiscount1 = new PaymentSDKCardDiscount();
cardDiscount1.discountCards = ['4111', '40001'];
cardDiscount1.discountValue = 10;
cardDiscount1.discountTitle = 'Discount 10% on 4111,40001 cards';
cardDiscount1.isPercentage = true;

let cardDiscount2 = new PaymentSDKCardDiscount();
cardDiscount2.discountCards = ['42222', '40002'];
cardDiscount2.discountValue = 5;
cardDiscount2.discountTitle = 'Discount 5 EGP on 42222,40002 cards';
cardDiscount2.isPercentage = false;

configuration.cardDiscounts = Array.of(cardDiscount1, cardDiscount2);
````

## Card Validation

* The Payment SDK allows you to customize BIN-based discounts through the `PaymentSDKCardApproval`
  class, which collects approval details via an API.

```javascript
let cardApproval = new PaymentSDKCardApproval("https://webhook.site/8c1ba496-18b9-46c0-9277-94e8a883344b", 8, true);
configuration.cardApproval = cardApproval;
```

## Show/Hide Card Scanner

```javascript
configuration.hideCardScanner = true
```

## Theme Customization

![UI guide](https://user-images.githubusercontent.com/13621658/109432213-d7981380-7a12-11eb-9224-c8fc12b0024d.jpg)

### iOS

- **Theme**: <br />Create an instance from the class `PaymentTheme` and customize the theme.

```javascript
let theme = new PaymentSDKTheme()
theme.backgroundColor = "a83297"
theme.primaryColor = "956596"
// Set the merchant logo
const merchantLogo = require('./Logo.png');
const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource');
const resolvedMerchantLogo = resolveAssetSource(merchantLogo);
theme.merchantLogo = resolvedMerchantLogo

configuration.theme = theme
```

- **Localization**:
  <br />Use the keys from our localization string
  files ([English][iosenglish], [Arabic][iosarabic]), then add the same key to your app localizable
  string file and add your custom string.

### Android

- **Theme**: <br />Edit your `styles.xml` to customize the theme.

````xml

<resources>
  // to override colors
  <color name="payment_sdk_primary_color">#5C13DF</color>
  <color name="payment_sdk_secondary_color">#FFC107</color>
  <color name="payment_sdk_primary_font_color">#111112</color>
  <color name="payment_sdk_secondary_font_color">#6D6C70</color>
  <color name="payment_sdk_separators_color">#FFC107</color>
  <color name="payment_sdk_stroke_color">#673AB7</color>
  <color name="payment_sdk_button_text_color">#FFF</color>
  <color name="payment_sdk_title_text_color">#FFF</color>
  <color name="payment_sdk_button_background_color">#3F51B5</color>
  <color name="payment_sdk_background_color">#F9FAFD</color>
  <color name="payment_sdk_card_background_color">#F9FAFD</color>

  // to override dimens
  <dimen name="payment_sdk_primary_font_size">17sp</dimen>
  <dimen name="payment_sdk_secondary_font_size">15sp</dimen>
  <dimen name="payment_sdk_separator_thickness">1dp</dimen>
  <dimen name="payment_sdk_stroke_thickness">.5dp</dimen>
  <dimen name="payment_sdk_input_corner_radius">8dp</dimen>
  <dimen name="payment_sdk_button_corner_radius">8dp</dimen>

</resources>
````

- **Merchant Logo**:

```javascript
let theme = new PaymentSDKTheme()

// Set the merchant logo
const merchantLogo = require('./Logo.png');
const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource');
const resolvedMerchantLogo = resolveAssetSource(merchantLogo);
theme.merchantLogo = resolvedMerchantLogo

configuration.theme = theme
```

- **Localization**:
  To override your strings you can find the keys with the default values here
  [English][english], [Arabic][arabic].

## Demo application

Check our complete examples ([React-Native][example], [Expo][expoexample]).

<img src="https://user-images.githubusercontent.com/13621658/109432386-905e5280-7a13-11eb-847c-63f2c554e2d1.png" width="370" alt=''>

## License

See [LICENSE][license].

## Paytabs

[Support][1] | [Terms of Use][2] | [Privacy Policy][3]

[1]: https://www.paytabs.com/en/support/

[2]: https://www.paytabs.com/en/terms-of-use/

[3]: https://www.paytabs.com/en/privacy-policy/

[license]: https://github.com/paytabscom/react-native-paytabs-library/blob/master/LICENSE

[applepayguide]: https://github.com/paytabscom/react-native-paytabs-library/blob/master/ApplePayConfiguration.md

[example]: https://github.com/paytabscom/react-native-paytabs-library/tree/master/example

[expoexample]: https://github.com/paytabscom/react-native-paytabs-library/tree/master/expo-example

[english]: https://github.com/paytabscom/paytabs-android-library-sample/blob/master/res/strings.xml

[arabic]: https://github.com/paytabscom/paytabs-android-library-sample/blob/master/res/strings-ar.xml

[iosenglish]: https://github.com/paytabscom/paytabs-ios-library-sample/blob/master/en.strings

[iosarabic]: https://github.com/paytabscom/paytabs-ios-library-sample/blob/master/ar.strings