react-native-paypal
A Cross platform React Native interface for the PayPal Payment UI. Supports both iOS and Android currently, but can be used seperately.
Usage
--
Initiating a payment is as simple as creating a single promise
let PayPal = require('react-native-paypal');
PayPal.paymentRequest({
clientId: 'AbyfNDFV53djg6w4yYgiug_JaDfBSUiYI7o6NM9HE1CQ_qk9XxbUX0nwcPXXQHaNAWYtDfphQtWB3q4R',
environment: PayPalAndroid.SANDBOX,
price: '42.00',
currency: 'USD',
description: 'PayPal Test'
}).then((confirm, payment) => console.log('Paid'); /* At this point you should verify payment independently */)
.catch((error_code) => console.error('Failed to pay through PayPal'));
Callback parameters:
If all goes OK with the payment than the paymentRequest promise is resolved with
the following arguments as JSON strings:
- A confirm:
{
"client": {
"environment": "mock",
"paypal_sdk_version": "2.12.4",
"platform": "Android",
"product_name": "PayPal-Android-SDK"
},
"response": {
"create_time": "2014-02-12T22:29:49Z",
"id": "PAY-6RV70583SB702805EKEYSZ6Y",
"intent": "sale",
"state": "approved"
},
"response_type": "payment"
}
- A payment:
{
"amount": "1.00",
"currency_code": "USD",
"short_description": "PayPal Test",
"intent": "sale"
}
Handling callbacks:
PayPal.paymentRequest(...).then(function (payment, confirm) {
sendPaymentToConfirmInServer(payment, confirm);
})
If anything fails the promise will be notify an error with a code which will be
one of:
- USER_CANCELLED
- INVALID_CONFIG
Handling failures:
PayPal.paymentRequest(...).catch(function (error_code) {
if (error_code == PayPal.USER_CANCELLED) {
// User didn't complete the payment
} else if (error_code == PayPal.INVALID_CONFIG) {
// Invalid config was sent to PayPal
}
})
Setup
Android
- Add react-navive-paypal to your project
npm install --save react-native-paypal
- Add the following to android/app/build.gradle
dependencies {
// ...
compile project(':react-native-paypal')
}
- Add the following to android/settings.gradle
include ':react-native-paypal'
project(':react-native-paypal').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-paypal/android')
- Edit android/src/.../MainActivity.java
// ...
import br.com.vizir.rn.paypal.PayPalPackage; // <--
import br.com.vizir.rn.paypal.PayPal; // <--
import android.content.Intent; // <--
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
// ...
private static final int PAY_PAL_REQUEST_ID = 9; // <-- Can be any unique number
private PayPalPackage payPalPackage; // <--
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
payPalPackage = new PayPalPackage(this, PAY_PAL_REQUEST_ID); // <--
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
// ...
.addPackage(payPalPackage) // <--
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// ...
}
// ...
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PAY_PAL_REQUEST_ID) {
payPalPackage.handleActivityResult(requestCode, resultCode, data); // <--
} else {
otherModulesHandlers(requestCode, resultCode, data);
}
}
}
iOS
Sample App
You'll find an iOS example in <root>/ios/Example/
. You will need to run npm install in that directory in order to download the dependencies required by the sample application. Note this sample still uses manual NativeModule usage, and you'll likely find the above Javascript simpler than the JS used in this sample.
Installation
Currently you have to install via npm
from GitHub (or change the version specifier in package.json
to MattFoley/react-native-paypal
):
npm install --save MattFoley/react-native-paypal
There will be an updated npm release shortly, which will allow
Install the PayPal-iOS-SDK
You then have to install the PayPal-iOS-SDK into node_modules/react-native-paypal/ios/lib/Paypal
Here's a one-liner to download and unpack version 2.13.0
:
mkdir -p node_modules/react-native-paypal/ios/lib/Paypal && curl -L --progress https://github.com/paypal/PayPal-iOS-SDK/archive/2.13.0.tar.gz | tar -xz - -C node_modules/react-native-paypal/ios/lib/Paypal --strip-components=1
Include PayPal as normally, following their directions. Their integration steps and iOS SDK can be found here. After doing that, also drag MFLReactNativePayPal.h and MFLReactNativePayPal.m into your project.
Add MFLReactNativePayPal.xcodeproj
Add node_modules/react-native-paypal/ios/MFLReactNativePayPal.xcodeproj
to the Libraries
group in iOS and link libMFLReactNativePayPal.a
as described in Step 2 of the
React Native Manual Linking docs.
Follow steps 4 and 5 of the PayPal instalation instructions, as well as the additional steps here. This has to be done for the main app, not for the library you included.
Manual Usage (iOS Only)
You can access the NativeModule directly on iOS using the following instructions, if you'd like to modify the functionality.
Initialization:
import {
NativeModules
} from 'react-native';
let MFLReactNativePayPal = NativeModules.MFLReactNativePayPal;
MFLReactNativePayPal.initializePaypalEnvironment(<environment>, "<Your client id>");
Environment Values that should be used here are declared in MFLReactNativePayPal.h
• Sandbox = 0
• Production = 1
• No Network = 2
Prepare a Payment:
MFLReactNativePayPal.preparePaymentOfAmount(<Amount as a Float>, <Currency Code>, <Short description>);
ie: MFLReactNativePayPal.preparePaymentOfAmount(100.00, "USD", "Bacon");
Prepare Configuration:
MFLReactNativePayPal.prepareConfigurationForMerchant(<Merchant Name>, <BOOL should accept credit cards>, <User email>);
MFLReactNativePayPal.prepareConfigurationForMerchant("Bacon Truck", true, "[email protected]");
Present the payment flow with a completion handler:
MFLReactNativePayPal.presentPaymentViewControllerForPreparedPurchase((error, payload) => {
if (error) {
//Handle Error
return;
} else {
console.log("payload: " + payload);
if (payload.status == 1) {
console.log(payload.confirmation);
} else {
console.log("User cancelled payment");
}
}
});
TODO:
* [ ] Android Sample App
* [ ] Refactor & cleanup
* [ ] Automated tests
* [ ] Future payment (subscriptions)
* [ ] Invoice and optional fields - https://github.com/MattFoley/react-native-paypal/issues/6