├── README.md ├── acceptance-logos ├── mastercard.svg └── visa.svg ├── examples ├── index.html ├── popup-custom.html ├── popup-donation.html ├── popup-minimal.html └── styles.css ├── package.json ├── plan.md └── standard-flow.md /README.md: -------------------------------------------------------------------------------- 1 | # Paylike Web SDK 2 | 3 | Payments for the web. 4 | 5 | [Sign up for a merchant account (it's free and instant)](https://paylike.io) 6 | 7 | Use the issue tracker to file any bug reports or feature requests. 8 | 9 | Make sure to use a key from a test account and set the `test` parameter, which 10 | will also allow you to test without https (e.g. locally). 11 | 12 | Need help? Reach out on email: [hello@paylike.io](https://paylike.io/contact). 13 | 14 | ## Examples 15 | 16 | ```html 17 | 18 | 35 | ``` 36 | 37 | - [Popup](examples/popup-custom.html) 38 | - [Popup with custom fields](examples/popup-donation.html) 39 | - [Popup for donations](examples/popup-minimal.html) 40 | 41 | See also the [standard flow example](standard-flow.md) which includes the 42 | following backend API calls. 43 | 44 | ## Reference 45 | 46 | ```js 47 | const paylike = Paylike({key: String}) 48 | paylike.pay(config, (err, r) => console.log(err, r)) 49 | 50 | // config 51 | { 52 | amount: { 53 | currency: String, // ISO 4217 (e.g. "EUR") 54 | exponent: Number, // the number of fractional digits 55 | value: Number, // integer 56 | }, 57 | // the amount to be paid now, can be omitted for "save card" (see "Plans" 58 | // and "unplanned") 59 | // example: {currency: 'EUR', exponent: 2, value: 1499} (EUR 14.99) 60 | 61 | test: Boolean, // MUST be set if using a test key 62 | title: String, // title text to show in popup 63 | description: String, // descriptive text to show in popup 64 | 65 | locale: String, // pin the popup to a locale (e.g. en_US or en) 66 | // defaults to that of the browser 67 | 68 | text: String, 69 | // text on customer bank statement (SEE NOTES BELOW) 70 | 71 | custom: Object, 72 | // data to pass along (objects, nested objects, arrays and primitives) 73 | // visible in your dashboard 74 | // can be extracted using the API 75 | // keep it below 50K 76 | 77 | fields: Array, 78 | // see "Additional fields" section below 79 | 80 | plan: Array, // see "Plans" below 81 | unplanned: { 82 | // see "Unplanned" below 83 | merchant: Boolean, 84 | customer: Boolean, 85 | }, 86 | 87 | key: String, 88 | // override key from factory function 89 | } 90 | 91 | // err 92 | 'superseded' // the payment popup was closed by the user 93 | 'closed' // another payment popup was opened, closing this one 94 | Error // in case of unexpected events 95 | ``` 96 | 97 | All configuration fields are optional, but either `amount` or one of `plan` and 98 | `unplanned` should be provided. All three may also be present (e.g. a gym 99 | subscription with an upfront payment, monthly charge, and pay-as-you-go 100 | classes). 101 | 102 | `key` must be provided for either the factory function or `.pay`. 103 | 104 | The callback is called in "node-style": `callback(error, response)`. 105 | 106 | The response will look like this: 107 | 108 | ```js 109 | { 110 | transaction: { 111 | id: String, 112 | }, 113 | 114 | custom: { ... }, 115 | } 116 | ``` 117 | 118 | If the user closes the popup the `error` variable will have a value of `closed`. 119 | 120 | If another popup is opened in the meantime `error` variable will have a value of 121 | `superseded`. 122 | 123 | ### Currency (`amount.currency`) 124 | 125 | All supported currencies are listed at https://github.com/paylike/currencies. 126 | 127 | ### Text (`text`) 128 | 129 | The field is optional. If none is provided, the merchant's "descriptor" is used. 130 | 131 | The maximum length is 1024 characters. For payment cards (such as Visa, 132 | Mastercard, etc.) the length must be at least 2 characters, it will be truncated 133 | to 22 characters, and only characters matching `/[\x20-\x7E]/` are accepted 134 | (others are replaced). 135 | 136 | The text is forwarded to be shown on the customer's bank statement or similar. 137 | There is no guarantee as to how the issuer of the customer's payment instrument 138 | (e.g. their bank) will use or show this text. 139 | 140 | ### Additional fields (`fields`) 141 | 142 | ```js 143 | paylike.pay( 144 | { 145 | amount: 1000, 146 | currency: 'DKK', 147 | fields: [ 148 | // simple custom field 149 | 'name', 150 | 151 | // elaborate custom field 152 | { 153 | name: 'email', 154 | label: 'E-mail', // same as `name` if not provided 155 | type: 'email', 156 | placeholder: 'user@example.com', 157 | required: true, 158 | value: email, // provide a default value 159 | }, 160 | ], 161 | }, 162 | cb 163 | ) 164 | ``` 165 | 166 | If you add a field with a name of "amount" it will allow users to dynamically 167 | choose the transaction amount. 168 | [See this example](https://sdk.paylike.io/examples/popup-donation.html). 169 | 170 | ### Test scenarioes (`test`) 171 | 172 | The `test` parameter may be used to trigger specific payment flows and 173 | scenarios. The format is described in 174 | [the API reference documentation for the payments API](https://github.com/paylike/api-reference/blob/master/payments/index.md#test). 175 | 176 | ### Save (tokenize) a card for later use (subscriptions, installments, pay-as-you-go etc.) 177 | 178 | To reuse a card for later transactions from your server, specify at least one of 179 | `plan` and `unplanned`. 180 | 181 | You can omit `amount` entirely if no amount is due immedately, but it can 182 | validly be combined with `plan` and `unplanned` for a purchase. 183 | 184 | Later on create a transaction from your server using our API: 185 | [create a transaction using a previous transaction](https://github.com/paylike/api-docs#using-a-previous-transaction). 186 | 187 | Make sure to read our section about 188 | [recurring payments](https://github.com/paylike/api-docs#recurring-payments). 189 | 190 | #### Plans (`plan`) 191 | 192 | Please see [this document](plan.md). 193 | 194 | This is required for planned subsequent payments to ensure compliance and high 195 | approval rates. 196 | 197 | ##### Example 198 | 199 | ```js 200 | { 201 | plan: [ 202 | { 203 | amount: {currency: 'EUR', value: 999, exponent: 2}, 204 | repeat: { 205 | interval: {unit: 'month'}, 206 | }, 207 | } 208 | ], 209 | } 210 | ``` 211 | 212 | A monthly subscription of EUR 9.99. 213 | 214 | #### Unplanned (`unplanned`) 215 | 216 | Flag the types (one or more) of unplanned payments the card could be used for in 217 | the future. The supported types are: 218 | 219 | - `customer` (initiated by the customer from your website/application) 220 | - `merchant` (initiated by the merchant or an off-site customer) 221 | 222 | This is required for unplanned subsequent payments to ensure compliance and high 223 | approval rates. 224 | 225 | ##### Example 226 | 227 | You wish to automatically charge the card for each ride in a roller coaster: 228 | 229 | ```js 230 | { 231 | // ... 232 | unplanned: {merchant: true}, 233 | } 234 | ``` 235 | 236 | You allow customers to save their card for faster checkout in the future: 237 | 238 | ```js 239 | { 240 | // ... 241 | unplanned: {customer: true}, 242 | } 243 | ``` 244 | 245 | The difference between the two scenarios is whether the customer is triggering 246 | the purchase from a device capable of authenticating the payment. 247 | 248 | ## Custom payment form 249 | 250 | If you are looking to build a custom payment form, make sure to visit these 251 | tools to ease the development: 252 | 253 | - [JavaScript (web) client](https://github.com/paylike/js-client) 254 | - [Card form helpers](https://github.com/paylike/js-card-form-tools) 255 | 256 | In the 257 | [payments API reference](https://github.com/paylike/api-reference/blob/master/payments/index.md) 258 | you can find the relevant details for submitting payments. 259 | 260 | ## Browser support 261 | 262 | The SDK is tested in all regular browsers capable of conducting modern secure 263 | communication as required for payments. 264 | 265 | If you have issues with an environment, please open an issue or drop us an email 266 | at hello@paylike.io. 267 | -------------------------------------------------------------------------------- /acceptance-logos/mastercard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /acceptance-logos/visa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | Paylike.io SDK examples 14 | 15 | 16 |

Examples

17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/popup-custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | Paylike.io SDK examples 14 | 15 | 16 |

17 | This example uses most features of the popup and attaches custom 18 | meta data to the transaction. 19 |

20 | 21 | 25 | 26 | SDK documentation on GitHub 27 | 28 | 29 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /examples/popup-donation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | Paylike.io SDK examples 14 | 15 | 16 |

This is an example of a simple donation style popup.

17 | 18 | 22 | 23 | SDK documentation on GitHub 24 | 25 | 26 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /examples/popup-minimal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | Paylike.io SDK examples 14 | 15 | 16 |

This example is the minimal implementation of the popup.

17 | 18 | 22 | 23 | SDK documentation on GitHub 24 | 25 | 26 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /examples/styles.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); 2 | 3 | body { 4 | margin: 0; 5 | padding: 1em; 6 | text-align: center; 7 | font-family: 'Open Sans', sans-serif; 8 | font-size: 12px; 9 | color: #333; 10 | } 11 | 12 | * { 13 | max-width: 35em; 14 | } 15 | 16 | ul { 17 | list-style-type: none; 18 | padding: 0; 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@paylike/sdk", 3 | "repository": "paylike/sdk", 4 | "prettier": { 5 | "semi": false, 6 | "singleQuote": true, 7 | "useTabs": true, 8 | "bracketSpacing": false, 9 | "tabWidth": 4, 10 | "proseWrap": "always", 11 | "overrides": [ 12 | { 13 | "files": "*.md", 14 | "options": { 15 | "useTabs": false, 16 | "tabWidth": 2 17 | } 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plan.md: -------------------------------------------------------------------------------- 1 | # Payment plans (`plan`) 2 | 3 | A payment plan represents an agreement between customer and merchant about 4 | future payments such a subscription, or installments. They are defined using the 5 | `plan` field. 6 | 7 | Please note that the payment plan is _not automatically executed_. This field 8 | merely represents the agreement made between customer and merchant as of this 9 | payment order. 10 | 11 | Be aware that there is no guarantee for a future payment to succeed despite the 12 | payment plan. Read our section on 13 | [recurring payments](https://github.com/paylike/api-docs#recurring-payments) and 14 | plan accordingly. 15 | 16 | Future payments may later be created from your server using 17 | [our API by referencing the `transaction.id`](https://github.com/paylike/api-docs#using-a-previous-transaction). 18 | 19 | Each component represents an amount (`amount`) to be due at a future date either 20 | once (`scheduled`) or repeated. 21 | 22 | Repeating components begin at `repeat.first` (defaulting to "now") and repeat 23 | indefinitely or `repeat.count` times at a fixed interval (`repeat.interval`). 24 | Subsequent payments occur each `repeat.interval.unit * repeat.interval.value` 25 | after `repeat.first`. `repeat.interval.value` defaults to `1`. 26 | 27 | ## Limitations 28 | 29 | - `repeat.count` is optional only for the last component 30 | - `scheduled` and `repeat.first` must be chronologically later than the previous 31 | component 32 | 33 | ## Examples 34 | 35 | ### Monthly subscription of €9 36 | 37 | ```js 38 | const plan = [ 39 | { 40 | amount: {currency: 'EUR', value: 900, exponent: 2}, 41 | repeat: { 42 | interval: {unit: 'month'}, 43 | }, 44 | }, 45 | ] 46 | ``` 47 | 48 | The starting date, and first payment, is assumed to be "now" and thus the next 49 | payment is exactly one month from now. The `amount` for the payment should be €9 50 | to immediately authorize the first amount. 51 | 52 | ### Monthly subscription of €79 with a 14 days trial 53 | 54 | ```js 55 | const plan = [ 56 | { 57 | amount: {currency: 'EUR', value: 7900, exponent: 2}, 58 | repeat: { 59 | first: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000), 60 | interval: {unit: 'month'}, 61 | }, 62 | }, 63 | ] 64 | ``` 65 | 66 | The payment's `amount` would simply be omitted unless the trial has an upfront 67 | price. 68 | 69 | ### Biweekly (every other week) subscription of €9 charged on Fridays 70 | 71 | ```js 72 | const plan = [ 73 | { 74 | amount: {currency: 'EUR', value: 900, exponent: 2}, 75 | repeat: { 76 | first: new Date('2021-01-22'), // next upcoming Friday 77 | interval: { 78 | unit: 'week', 79 | value: 2, 80 | }, 81 | }, 82 | }, 83 | ] 84 | ``` 85 | 86 | The payment's `amount` can be used to charge a prorated amount for the time 87 | between "now" and the first subscription payment if desirable. 88 | 89 | ### Three months at a reduced rate 90 | 91 | ```js 92 | const plan = [ 93 | { 94 | amount: {currency: 'EUR', value: 999, exponent: 2}, 95 | repeat: { 96 | interval: {unit: 'month'}, 97 | count: 3, 98 | }, 99 | }, 100 | { 101 | amount: {currency: 'EUR', value: 1999, exponent: 2}, 102 | repeat: { 103 | interval: {unit: 'month'}, 104 | }, 105 | }, 106 | ] 107 | ``` 108 | 109 | ### Pay a €1100 debt at €400 monthly (installment) 110 | 111 | ```js 112 | const plan = [ 113 | { 114 | amount: {currency: 'EUR', value: 400, exponent: 2}, 115 | scheduled: new Date('2022-02-01'), 116 | }, 117 | { 118 | amount: {currency: 'EUR', value: 400, exponent: 2}, 119 | scheduled: new Date('2022-03-01'), 120 | }, 121 | { 122 | amount: {currency: 'EUR', value: 300, exponent: 2}, 123 | scheduled: new Date('2022-04-01'), 124 | }, 125 | ] 126 | ``` 127 | -------------------------------------------------------------------------------- /standard-flow.md: -------------------------------------------------------------------------------- 1 | # Example transaction flow 2 | 3 | 1. During checkout (frontend) 4 | 5 | 1. Open the payment popup. Include at least an order reference (or a hash) in 6 | the custom data field which uniquely identifies the order. 7 | 8 | 2. The callback for the popup will receive a transaction ID on a succesful 9 | payment. Send it to the server using a hidden form, a redirect (query) or 10 | an AJAX call. 11 | 12 | ```html 13 | 14 | 33 | ``` 34 | 35 | 2. During checkout (backend) 36 | 37 | Verify the payment by fetching the transaction: 38 | 39 | ```bash 40 | curl https://api.paylike.io/transactions/ -u : 41 | ``` 42 | 43 | Check that the currency, amount and unique order reference match what you 44 | have on record and complete the order. If something does not match, the 45 | payment should fail as the data could have been tampered. 46 | 47 | A cryptographic hash of the critical fields, including any internal 48 | references, could also be added to the `custom` object and checked against a 49 | re-computed hash. 50 | 51 | 3. When shipping/delivering 52 | 53 | Once you ship the product, capture the transaction: 54 | 55 | ```bash 56 | curl https://api.paylike.io/transactions//captures -u : -d currency=EUR -d amount=1499 57 | ``` 58 | 59 | Amount being EUR 14,99. 60 | 61 | In the case of digital products, preorders, vouchers, tickets or other "instant 62 | delivery"-scenarios where you would want to employ "instant capture", simply do 63 | the capture immediately after the verification in step 2. 64 | 65 | See also the 66 | [full API reference and clients](https://github.com/paylike/api-docs) for 67 | backend integration. 68 | --------------------------------------------------------------------------------