Skip to content

Commit fef7bb7

Browse files
authored
Merge pull request #3 from naoufal/rn-payments
Release React Native Payments
2 parents 2e1ed7a + 658ac36 commit fef7bb7

File tree

100 files changed

+34538
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+34538
-0
lines changed

.babelrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"plugins": [
3+
"transform-class-properties"
4+
],
5+
"presets": ["react-native"]
6+
}

.flowconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[ignore]
2+
3+
[include]
4+
5+
[libs]
6+
7+
[options]
8+
unsafe.enable_getters_and_setters=true

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# System
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
24+
# npm
25+
#
26+
node_modules/
27+
28+
# editors
29+
#
30+
jsconfig.json
31+
.vscode/*
32+
33+
# project
34+
#
35+
coverage

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
examples
2+
.babelrc

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- "node"
4+
script:
5+
- yarn test -- --verbose --coverage

README.md

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
> This project is currently in __beta and APIs are subject to change.__
2+
3+
# React Native Payments
4+
[![react-native version](https://img.shields.io/badge/react--native-0.41-0ba7d3.svg?style=flat-square)](http://facebook.github.io/react-native/releases/0.40)
5+
[![npm](https://img.shields.io/npm/v/react-native-payments.svg?style=flat-square)](https://www.npmjs.com/package/react-native-payments)
6+
[![npm](https://img.shields.io/npm/dm/react-native-payments.svg?style=flat-square)](https://www.npmjs.com/package/react-native-payments)
7+
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
8+
9+
Accept Payments with Apple Pay and using the [Payment Request API](https://paymentrequest.show).
10+
11+
__Features__
12+
- __Simple.__ No more checkout forms.
13+
- __Effective__. Faster checkouts that increase conversion.
14+
- __Cross-platform.__ Share your payments code between iOS and web apps.
15+
16+
<img width="280px" src="https://user-images.githubusercontent.com/1627824/27758096-9fc6bf9a-5dc1-11e7-9d8f-b2d409302fc7.gif" />
17+
18+
---
19+
20+
## Table of Contents
21+
- [Demo](#demo)
22+
- [Installation](#installation)
23+
- [Usage](#usage)
24+
- [API](#api)
25+
- [Resources](#resources)
26+
- [License](#license)
27+
28+
## Demo
29+
You can run the demo by cloning the project and running:
30+
31+
```shell
32+
$ yarn run:demo
33+
```
34+
35+
In a rush? Check out the [browser version](https://rnp.nof.me) of the demo.
36+
37+
_Note that you'll need to run it from a browser with [Payment Request support](https://caniuse.com/#search=payment%20request)._
38+
39+
## Installation
40+
First, download the package:
41+
```shell
42+
$ yarn add react-native-payments
43+
```
44+
Second, link the native dependencies:
45+
```shell
46+
$ react-native link react-native-payments
47+
```
48+
49+
## Usage
50+
- [Registering as a Merchant](#registering-as-a-merchant)
51+
- [Importing the Library](#importing-the-library)
52+
- [Initializing the Payment Request](#initializing-the-payment-request)
53+
- [Displaying the Payment Request](#displaying-the-payment-request)
54+
- [Dismissing the Payment Request](#dismissing-the-payment-request)
55+
- [Requesting Contact Information](#requesting-contact-information)
56+
- [Requesting a Shipping Address](#requesting-a-shipping-address)
57+
- [Processing Payments](#processing-payments)
58+
59+
### Registering as a Merchant
60+
Before you can start accepting payments with Apple Pay, there are a few steps you'll need to go through:
61+
62+
1. Register as an Apple Developer
63+
1. Obtain a merchant ID
64+
2. Enable Apple Pay in your app
65+
66+
Apple has a documentation on how to do both of these in their _[Configuring your Environment](https://developer.apple.com/library/content/ApplePay_Guide/Configuration.html)_ guide.
67+
68+
### Importing the Library
69+
Once Apple Pay is enabled in your app, jump into your app's entrypoint and make the `PaymentRequest` globally available to your app.
70+
71+
```es6
72+
// index.ios.js
73+
global.PaymentRequest = require('react-native-payments').PaymentRequest;
74+
```
75+
76+
### Initializing the Payment Request
77+
To initialize a Payment Request, you'll need to provide `PaymentMethodData` and `PaymentDetails`.
78+
79+
#### Payment Method Data
80+
The Payment Method Data is where you defined the forms of payment that you accept. To enable Apple Pay, we'll define a `supportedMethod` of `apple-pay`. We're also required to pass a `data` object to configures Apple Pay. This is where we provide our merchant id, define the supported card types and the currency we'll be operating in.
81+
82+
```es6
83+
const METHOD_DATA = [{
84+
supportedMethods: ['apple-pay'],
85+
data: {
86+
merchantIdentifier: 'merchant.com.your-app.namespace',
87+
supportedNetworks: ['visa', 'mastercard', 'amex'],
88+
countryCode: 'US',
89+
currencyCode: 'USD'
90+
}
91+
}];
92+
```
93+
94+
#### Payment Details
95+
Payment Details is where define transaction details like display items, a total and optionally shipping options.
96+
97+
Google has excellent documentation for [Defining Payment Details](https://developers.google.com/web/fundamentals/discovery-and-monetization/payment-request/deep-dive-into-payment-request#defining_payment_details).
98+
99+
```es6
100+
const DETAILS = {
101+
id: 'basic-example',
102+
displayItems: [
103+
{
104+
label: 'Movie Ticket',
105+
amount: { currency: 'USD', value: '15.00' }
106+
}
107+
],
108+
total: {
109+
label: 'Merchant Name',
110+
amount: { currency: 'USD', value: '15.00' }
111+
}
112+
};
113+
```
114+
115+
Once you've defined your `methodData` and `details`, you're ready to initialize your Payment Request.
116+
117+
```es6
118+
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS);
119+
```
120+
121+
### Displaying the Payment Request
122+
Now that you've setup your Payment Request, displaying it is as simple as calling the `show` method.
123+
124+
```es6
125+
paymentRequest.show();
126+
```
127+
128+
<details>
129+
<summary><strong>See Screenshot</strong></summary>
130+
<br/>
131+
<img width="250px" src="https://user-images.githubusercontent.com/1627824/27548765-be9121c0-5a4e-11e7-8e45-4b460e314e6a.png" />
132+
133+
</details>
134+
135+
### Dismissing the Payment Request
136+
You can dismiss the Payment Request at any point by calling the `abort` method.
137+
138+
```es6
139+
paymentRequest.abort();
140+
```
141+
142+
### Requesting Contact Information
143+
Some apps may require contact information from a user. You can do so by providing a [`PaymentOptions`]() as a third argument when initializing a Payment Request. Using Payment Options, you can request a contact name, phone number and/or email.
144+
145+
#### Requesting a Contact Name
146+
Set `requestPayerName` to `true` to request a contact name.
147+
148+
```es6
149+
const OPTIONS = {
150+
requestPayerName: true
151+
};
152+
```
153+
154+
<details>
155+
<summary><strong>See Screenshot</strong></summary>
156+
<br/>
157+
<img width="250px" src="https://user-images.githubusercontent.com/1627824/27549933-9be15be6-5a52-11e7-868a-abcfc8867968.png" />
158+
159+
</details>
160+
161+
162+
#### Requesting a Phone Number
163+
Set `requestPayerPhone` to `true` to request a phone number.
164+
165+
```es6
166+
const OPTIONS = {
167+
requestPayerPhone: true
168+
};
169+
```
170+
171+
<details>
172+
<summary><strong>See Screenshot</strong></summary>
173+
<br/>
174+
<img width="250px" src="https://user-images.githubusercontent.com/1627824/27549958-b6732160-5a52-11e7-8813-3beeeed03b9c.png" />
175+
176+
</details>
177+
178+
#### Requesting an Email Address
179+
Set `requestPayerEmail` to `true` to request an email address.
180+
181+
```es6
182+
const OPTIONS = {
183+
requestPayerEmail: true
184+
};
185+
```
186+
187+
<details>
188+
<summary><strong>See Screenshot</strong></summary>
189+
<br/>
190+
<img width="250px" src="https://user-images.githubusercontent.com/1627824/27549968-c172ac34-5a52-11e7-973d-8d06a3beb5ce.png" />
191+
192+
</details>
193+
<br/>
194+
195+
You can also request all three by setting them all to `true`.
196+
197+
```es6
198+
const OPTIONS = {
199+
requestPayerName: true,
200+
requestPayerPhone: true,
201+
requestPayerEmail: true
202+
};
203+
```
204+
205+
### Requesting a Shipping Address
206+
Requesting a shipping address is done in three steps.
207+
208+
First, you'll need to set `requestShipping` to `true` within `PaymentOptions`.
209+
210+
```es6
211+
const OPTIONS = {
212+
requestShipping: true
213+
};
214+
```
215+
216+
Second, you'll need to include `shippingOptions` in your Payment Details.
217+
218+
```diff
219+
const DETAILS = {
220+
id: 'basic-example',
221+
displayItems: [
222+
{
223+
label: 'Movie Ticket',
224+
amount: { currency: 'USD', value: '15.00' }
225+
}
226+
],
227+
+ shippingOptions: [{
228+
+ id: 'economy',
229+
+ label: 'Economy Shipping',
230+
+ amount: { currency: 'USD', value: '0.00' },
231+
+ detail: 'Arrives in 3-5 days' // `detail` is specific to React Native Payments
232+
+ }],
233+
total: {
234+
label: 'Merchant Name',
235+
amount: { currency: 'USD', value: '15.00' }
236+
}
237+
};
238+
```
239+
240+
Lastly, you'll need to register event listeners for when a user selects a `shippingAddress` and/or a `shippingOption`. In the callback each event, you'll need to provide new `PaymentDetails` that will update your PaymentRequest.
241+
242+
```es6
243+
paymentRequest.addEventListener('shippingaddresschange', e => {
244+
const updatedDetails = getUpdatedDetailsForShippingAddress(paymentRequest.shippingAddress;
245+
246+
e.updateWith(updatedDetails);
247+
});
248+
249+
paymentRequest.addEventListener('shippingaddresschange', e => {
250+
const updatedDetails = getUpdatedDetailsForShippingOption(paymentRequest.shippingOption);
251+
252+
e.updateWith(updatedDetails);
253+
});
254+
```
255+
256+
For a deeper dive on handling shipping in Payment Request, checkout Google's _[Shipping in Payment Request](https://developers.google.com/web/fundamentals/discovery-and-monetization/payment-request/deep-dive-into-payment-request#shipping_in_payment_request_api)_.
257+
258+
### Processing Payments
259+
Now that we know how to initialize, display, and dismiss a Payment Request, let's take a look at how to process payments.
260+
261+
When a user accepts to pay, `PaymentRequest.show` will resolve to a Payment Response.
262+
263+
```es6
264+
paymentRequest.show()
265+
.then(paymentResponse => {
266+
// Your payment processing code goes here
267+
268+
return processPayment(paymentResponse);
269+
});
270+
```
271+
272+
There are two ways to process Apple Pay payments -- on your server or using a payment platform's native library.
273+
274+
#### Processing Payments on Your Server
275+
If you're equiped to Apple Pay payments on your server, all you have to do is send the Payment Response's `transactionIdentifier` and `paymentData` to your server.
276+
277+
```es6
278+
import { NativeModules } from 'react-native';
279+
280+
paymentRequest.show()
281+
.then(paymentResponse => {
282+
const { transactionIdentifier, serializedPaymentData } = paymentResponse.details;
283+
284+
return fetch('...', {
285+
method: 'POST',
286+
body: {
287+
transactionIdentifier,
288+
serializedPaymentData
289+
}
290+
})
291+
.then(res => res.json())
292+
.then(successHandler)
293+
.catch(errorHandler)
294+
});
295+
```
296+
297+
You can learn more about server-side decrypting of Payment Tokens on Apple's [Payment Token Format Reference](https://developer.apple.com/library/content/documentation/PassKit/Reference/PaymentTokenJSON/PaymentTokenJSON.html) documentation.
298+
299+
#### Processing Payments with a Payment Platform
300+
Documentation coming soon.
301+
302+
## API
303+
### [PaymentRequest](https://github.com/naoufal/react-native-payments/tree/master/docs/PaymentRequest.md)
304+
### [PaymentRequestUpdateEvent](https://github.com/naoufal/react-native-payments/tree/master/docs/PaymentRequestUpdateEvent.md)
305+
### [PaymentResponse](https://github.com/naoufal/react-native-payments/tree/master/docs/PaymentResponse.md)
306+
307+
## Resources
308+
### Payment Request
309+
- [Introducing the Payment Request API](https://developers.google.com/web/fundamentals/discovery-and-monetization/payment-request)
310+
- [Deep Dive into the Payment Request API](https://developers.google.com/web/fundamentals/discovery-and-monetization/payment-request/deep-dive-into-payment-request)
311+
- [W3C API Working Draft](https://www.w3.org/TR/payment-request/)
312+
- [Web Payments](https://www.youtube.com/watch?v=U0LkQijSeko)
313+
- [The Future of Web Payments](https://www.youtube.com/watch?v=hU89pPBmhds)
314+
315+
### Apple Pay
316+
- [Getting Started with Apple Pay](https://developer.apple.com/apple-pay/get-started)
317+
- [Configuring your Environment](https://developer.apple.com/library/content/ApplePay_Guide/Configuration.html)
318+
- [Processing Payments](https://developer.apple.com/library/content/ApplePay_Guide/ProcessPayment.html#//apple_ref/doc/uid/TP40014764-CH5-SW4)
319+
- [Payment Token Format Reference](https://developer.apple.com/library/content/documentation/PassKit/Reference/PaymentTokenJSON/PaymentTokenJSON.html#//apple_ref/doc/uid/TP40014929)
320+
321+
# License
322+
Licensed under the MIT License, Copyright © 2017, [Naoufal Kadhom](https://twitter.com/naoufal).
323+
324+
See [LICENSE](https://github.com/naoufal/react-native-payments/blob/master/LICENSE) for more information.

0 commit comments

Comments
 (0)