UNPKG

@fawry_pay/rn-fawry-pay-sdk

Version:
548 lines (424 loc) 20.6 kB
# FawryPay React Native SDK (Nitro Modules) This is the only official FawryPay SDK package for React Native, powered by [Nitro Modules](https://nitro.margelo.com/) for superior performance and seamless native integration. ## Table of Contents - [Introduction](#introduction) - [Installation](#installation) - [Getting Started](#getting-started) - [Step 1: Create a FawryPay Account](#step-1-create-a-fawrypay-account) - [Step 2: Initialize the SDK](#step-2-initialize-the-sdk) - [Step 3: Present Payment Options](#step-3-present-payment-options) - [Step 4: Present Card Manager (Optional)](#step-4-present-card-manager-optional) - [Step 5: Event Listeners (Recommended)](#step-5-event-listeners-recommended) - [Platform-specific Notes](#platform-specific-notes) - [Android](#android) - [iOS](#ios) - [Customizing UI Colors](#customizing-ui-colors) - [Parameters Explained](#parameters-explained) - [API Reference](#api-reference) - [Sample Project](#sample-project) ## Introduction The FawryPay React Native SDK provides seamless integration for processing payments and managing cards within your React Native application. Built on Nitro Modules, this SDK offers: - ⚡ **Superior Performance**: Native module architecture with minimal overhead - 🔒 **Secure Payments**: Industry-standard security with 3D Secure support - 💳 **Card Management**: Save and manage customer payment methods - 🌐 **Multi-language Support**: Arabic and English interfaces - 📱 **Cross-platform**: Full iOS and Android support ## Expo Compatibility **❌ Expo Managed Workflow**: Not supported due to native module requirements **✅ Expo Bare Workflow**: Fully supported (equivalent to vanilla React Native) **✅ Vanilla React Native**: Fully supported #### How it works ![Fawrypay SDK Explained](https://raw.githubusercontent.com/FawryPay/Android-Fawrypay-Anonymous-sample/master/Docs/4.jpg) ## Installation ### Prerequisites - React Native 0.60+ - iOS 12.0+ / Android API 21+ - Node.js 16+ ### Step 1: Install the FawryPay SDK ```bash npm install @fawry_pay/rn-fawry-pay-sdk react-native-nitro-modules ``` > **Important**: `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/). ### Step 2: Platform Setup Follow the platform-specific setup instructions below. ## Getting Started ### Step 1: Create a FawryPay Account Before utilizing the FawryPay SDK, you must have a FawryPay merchant account. Visit the [FawryPay website](https://atfawry.com) to create an account if you don't already have one. ### Step 2: Initialize the SDK In your React Native project, import the necessary components and configure the FawryPay SDK: ```typescript import React, { useEffect, useRef } from 'react'; import { TouchableOpacity, Text, StyleSheet, View, Platform } from 'react-native'; import { startPayment, openCardsManager, addFawryListener, FawryEvents, } from '@fawry_pay/rn-fawry-pay-sdk'; import type { BillItems, MerchantInfo, CustomerInfo, FawryLaunchModel, FawryLanguages } from '@fawry_pay/rn-fawry-pay-sdk'; import uuid from 'react-native-uuid'; const cartItems: BillItems[] = [ { itemId: 'item1', description: 'Item 1 Description', quantity: '1', price: '300' }, { itemId: 'item2', description: 'Item 2 Description', quantity: '1', price: '200' }, { itemId: 'item3', description: 'Item 3 Description', quantity: '1', price: '500' }, ]; const merchant : Fawry.MerchantInfo = { merchantCode: 'YOUR MERCHANT CODE', merchantSecretCode: 'YOUR SECRET CODE', merchantRefNum: uuid.v4().toString(), }; const customer : Fawry.CustomerInfo = { customerName: 'Ahmed Kamal', customerMobile: '+1234567890', customerEmail: 'ahmed.kamal@example.com', customerProfileId: '12345', }; const fawryConfig : Fawry.FawryLaunchModel = { baseUrl: 'https://atfawry.fawrystaging.com/', lang: Fawry.FawryLanguages.ENGLISH, signature: '', allow3DPayment: false, skipReceipt: false, skipLogin: true, payWithCardToken: true, authCaptureMode: false, allowVoucher: true, items: cartItems, merchantInfo: merchant, customerInfo: customer, }; ``` ### Step 3: Present Payment Options To initiate the payment process, use the `startPayment` function: ```typescript const handlePayment = () => { // Generate new reference number for each transaction const updatedMerchant = { ...merchant, merchantRefNum: uuid.v4().toString() }; startPayment({ ...fawryConfig, merchantInfo: updatedMerchant }); }; ``` ### Step 4: Present Card Manager (Optional) Allow users to manage their saved cards: ```typescript const handleCardsManager = () => { openCardsManager( fawryConfig.baseUrl, fawryConfig.lang, fawryConfig.merchantInfo, fawryConfig.customerInfo ); }; ``` ### Step 5: Event Listeners (Recommended) Set up event listeners to handle payment responses and card manager events: ```typescript const App = () => { const removeListenerRef = useRef<(() => void) | null>(null); useEffect(() => { // Setup event listener removeListenerRef.current = addFawryListener((eventName, payload) => { try { const parsed = isValidJson(payload) ? JSON.parse(payload) : payload; switch(eventName) { case FawryEvents.EVENT_PAYMENT_COMPLETED: console.log('Payment completed:', parsed); // Handle successful payment // Navigate to success screen or update UI break; case FawryEvents.EVENT_ON_SUCCESS: console.log('Payment success:', parsed); // Handle general success break; case FawryEvents.EVENT_ON_FAIL: console.log('Payment failed:', parsed); // Handle payment failure // Show error message to user break; case FawryEvents.EVENT_CardManager_FAIL: console.log('Card manager error:', parsed); // Handle card manager errors break; case FawryEvents.EVENT_READY: console.log('SDK Ready'); // SDK is initialized and ready break; default: console.log(`Unhandled event: ${eventName}`, parsed); } } catch (e) { console.error(`Event parsing error for ${eventName}:`, e); console.warn(`Raw payload: ${payload}`); } }); // Cleanup on unmount return () => { removeListenerRef.current?.(); }; }, []); const isValidJson = (payload: string): boolean => { try { JSON.parse(payload); return true; } catch (e) { return false; } }; // Your component JSX... }; ``` ## Platform-specific Notes ### Android For Android integration, follow these additional steps: 1. Open `android/build.gradle` and add the FawryPay repository: ```gradle allprojects { repositories { google() mavenCentral() maven { url "https://nexusmobile.fawrystaging.com:2597/repository/maven-public/" } maven { url "https://maven.google.com" } jcenter() } } ``` 2. Ensure your `android/app/build.gradle` has minimum SDK version 21: ```gradle android { compileSdkVersion 34 defaultConfig { minSdkVersion 21 targetSdkVersion 34 } } ``` ### iOS For iOS integration, follow these steps: #### 1. Update your `Podfile`: ```ruby platform :ios, '16.6' ENV['RCT_NEW_ARCH_ENABLED'] = '1' # Load the custom RCTAppDelegate fix require_relative 'fix-rct-delegate.rb' # Resolve react_native_pods.rb with node require Pod::Executable.execute_command('node', ['-p', 'require.resolve( "react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]}, )', __dir__]).strip prepare_react_native_project! target 'YourAppName' do use_modular_headers! use_frameworks! # Add Folly explicitly pod 'RCT-Folly', :podspec => '../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec' config = use_native_modules! use_react_native!( :path => config[:reactNativePath], :hermes_enabled => true, :fabric_enabled => true, :new_arch_enabled => true, :app_path => "#{Pod::Config.instance.installation_root}/.." ) # Add FawryPay SDK pod 'FawryPaySDK' pre_install do |installer| Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {} installer.pod_targets.each do |pod| if ['React-RCTAppDelegate'].include?(pod.name) def pod.build_type; Pod::BuildType.dynamic_framework end end end end post_install do |installer| react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false ) installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES' config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.6' if target.name.start_with?('React-') config.build_settings['SWIFT_VERSION'] = '5.0' config.build_settings['ALWAYS_SEARCH_USER_PATHS'] = 'NO' config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++20' config.build_settings['OTHER_CPLUSPLUSFLAGS'] = '$(inherited) -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_CFG_NO_COROUTINES=1' end if ['React-RCTAppDelegate', 'React-RCTRuntime', 'React-Core'].include?(target.name) config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'NO' config.build_settings['OTHER_CFLAGS'] = '$(inherited) -Wno-error=implicit-function-declaration -Wno-error -Wno-nullability-completeness' config.build_settings['CLANG_WARN_DOCUMENTATION_COMMENTS'] = 'NO' end if ['FawryPaySDK'].include?(target.name) config.build_settings['SKIP_INSTALL'] = 'NO' config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' config.build_settings['SWIFT_COMPILATION_MODE'] = 'wholemodule' config.build_settings['GENERATE_INFOPLIST_FILE'] = 'YES' end end end end end ``` #### 2. Add the `fix-rct-delegate.rb` file: Create a file named `fix-rct-delegate.rb` in the root of your `ios/` directory with: ```ruby # fix-rct-delegate.rb module ReactNativePods class PodspecModifier def modify_react_rct_app_delegate(spec) spec.pod_target_xcconfig ||= {} spec.pod_target_xcconfig['GCC_PREPROCESSOR_DEFINITIONS'] = ['$(inherited)', 'RCT_EXTERN_MODULE=RCT_EXTERN', '_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES=1'] spec.pod_target_xcconfig['OTHER_CFLAGS'] = '$(inherited) -Wno-error -Wno-nullability-completeness -Wno-error=implicit-function-declaration' spec.pod_target_xcconfig['APPLICATION_EXTENSION_API_ONLY'] = 'NO' spec.compiler_flags = '-fno-objc-msgsend-selector-stubs' if ENV['RCT_NEW_ARCH_ENABLED'] == '1' spec.dependency 'React-RCTRuntime' spec.dependency 'React-NativeModulesApple' spec.dependency 'ReactCommon' end end end end ``` #### 3. Install iOS dependencies ```bash cd ios && pod install ``` #### ✅ Notes - This setup assumes React Native New Architecture (Fabric + TurboModules) - iOS minimum deployment target is `16.6` - Includes manual fixes for `RCTAppDelegate`, Xcode 15, and Swift interop - Ensures `FawryPaySDK` links properly with required runtime settings ## Customizing UI Colors ### Android 1. Navigate to `android/app/src/main/res/values/` 2. Create or edit `colors.xml`: ```xml <?xml version="1.0" encoding="utf-8"?> <resources> <color name="fawry_blue">#6F61C0</color> <color name="fawry_yellow">#A084E8</color> </resources> ``` ### iOS 1. In your iOS project, create `Style.plist`: ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>primaryColorHex</key> <string>#6F61C0</string> <key>secondaryColorHex</key> <string>#A084E8</string> <key>tertiaryColorHex</key> <string>#8BE8E5</string> <key>headerColorHex</key> <string>#6F61C0</string> </dict> </plist> ``` 2. Add `Style.plist` to your Xcode project. #### ✅ Notes - This setup assumes React Native New Architecture (Fabric + TurboModules) - iOS minimum deployment target is `16.6` - Includes manual fixes for `RCTAppDelegate`, Xcode 15, and Swift interop - Ensures `FawryPaySDK` links properly with required runtime settings ## Parameters Explained <br/>CustomerInfo | **PARAMETER** | **TYPE** | **REQUIRED** | **DESCRIPTION** | **EXAMPLE** | |---------------|---------------|---------------|---------------|---------------| | customerName | string | optional | \- | Name Name | | customerEmail | string | optional | \- | [email\@email.com](mailto:email@email.com){.email} | | customerMobile | string | optional | \- | +0100000000 | | customerProfileId | string | optional | mandatory in case of payments using saved cards | 1234 | <br/>MerchantInfo | **PARAMETER** | **TYPE** | **REQUIRED** | **DESCRIPTION** | **EXAMPLE** | |---------------|---------------|---------------|---------------|---------------| | merchantCode | string | required | Merchant ID provided during FawryPay account setup. | +/IPO2sghiethhN6tMC== | | merchantRefNum | string | required | Merchant's transaction reference number is random 10 alphanumeric digits. | A1YU7MKI09 | | merchantSecretCode | string | required | provided by support | 4b8jw3j2-8gjhfrc-4wc4-scde-453dek3d | <br>LaunchApplePayModel</br> - Used only on IOS | **PARAMETER** | **TYPE** | **REQUIRED** | **DESCRIPTION** | **EXAMPLE** | |---------------|---------------|---------------|---------------|---------------| | merchantID | String | required | Merchant ID provided during FawryPay account setup. | +/IPO2sghiethhN6tMC== | <br>LaunchCheckoutModel</br> | **PARAMETER** | **TYPE** | **REQUIRED** | **DESCRIPTION** | **EXAMPLE** | |---------------|---------------|---------------|---------------|---------------| | scheme | String | required | if you need use myfawry as payment method. <br/>BillItems | **PARAMETER** | **TYPE** | **REQUIRED** | **DESCRIPTION** | **EXAMPLE** | |---------------|---------------|---------------|---------------|---------------| | itemId | string | required | \- | 3w8io | | description | string | optional | \- | This is description | | price | string | required | \- | 200.00 | | quantity | string | required | \- | 1 | <br/>FawryLaunchModel | **PARAMETER** | **TYPE** | **REQUIRED** | **DESCRIPTION** | **EXAMPLE** | |---------------|---------------|---------------|---------------|---------------| | **CustomerInfo** | LaunchCustomerModel | optional | Customer information. | \- | | **MerchantInfo** | LaunchMerchantModel | required | Merchant information. | \- | | **launchCheckoutModel** | LaunchCheckoutModel | optional | if you need use myfawry as payment method. | **launchApplePayModel** | LaunchApplePayModel | optional | Used only on IOS. | \- | | **BillItems** | BillItems[] | required | Array of items which the user will buy, this array must be of type BillItems | \- | | paymentSignature | String | optional | You can create your own signature by concatenate the following elements on the same order and hash the result using **SHA-256** as explained:"merchantCode + merchantRefNum + customerProfileId (if exists, otherwise insert"") + itemId + quantity + Price (in tow decimal format like '10.00') + Secure hash keyIn case of the order contains multiple items the list will be **sorted** by itemId and concatenated one by one for example itemId1+ Item1quantity + Item1price + itemId2 + Item2quantity + Item2price | \- | | tokenizationSignature| String | optional | You can create your own signature by concatenate the following elements on the same order and hash the result using **SHA-256** as explained:"merchantCode + customerProfileId (if exists, otherwise insert"") + Secure hash key | \- | | allowVoucher | Boolean | optional - default value = false | True if your account supports voucher code | \- | | payWithCardToken | Boolean | required | If true, the user will pay with a card token ( one of the saved cards or add new card to be saved )If false, the user will pay with card details without saving | \- | | allow3DPayment | Boolean | optional - default value = false | to allow 3D secure payment make it "true" | \- | | skipReceipt | Boolean | optional - default value = false | to skip receipt after payment trial | \- | | skipLogin | Boolean | optional - default value = true | to skip login screen in which we take email and mobile | \- | | authCaptureMode | Boolean | optional - default value = false | depends on refund configuration: will be true when refund is enabled and false when refund is disabled | false | | baseUrl | String | required | Provided by the support team.Use staging URL for testing and switch for production to go live. | https://atfawry.fawrystaging.com (staging) <br/><br/> https://atfawry.com (production) | | lang | String | required | SDK language which will affect SDK's interface languages. | Fawry.FawryLanguages.ENGLISH | ## API Reference ### Functions #### `startPayment(model: FawryLaunchModel): void` Initiates the payment flow with the provided configuration. #### `openCardsManager(baseUrl: string, lang: FawryLanguages, merchantInfo: MerchantInfo, customerInfo: CustomerInfo): void` Opens the card management interface for users to manage saved payment methods. #### `addFawryListener(listener: FawryPayListener): () => void` Registers an event listener for payment and card management events. Returns a cleanup function. ### Events | Event | Description | Payload Type | |-------|-------------|--------------| | `EVENT_READY` | SDK initialization complete | string | | `EVENT_PAYMENT_COMPLETED` | Payment transaction completed | Object | | `EVENT_ON_SUCCESS` | Payment succeeded | Object | | `EVENT_ON_FAIL` | Payment failed | Object | | `EVENT_CardManager_FAIL` | Card manager error | Object | | `EVENT_COMPLETION_BLOCK` | Payment initialization | string | | `EVENT_PRE_COMPLETION` | Pre-payment setup | string | ### Types ```typescript type FawryLanguages = 'ENGLISH' | 'ARABIC'; type FawryPayListener = (eventName: string, payload: string) => void; ``` ## Sample Project For a complete implementation example, check out our sample project in the `example/` directory of this repository. ## Contributing See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. ## License MIT --- Made with [Nitro Modules](https://nitro.margelo.com/) and [create-react-native-library](https://github.com/callstack/react-native-builder-bob)