Pay Theory Web SDK
Live Install
npm install --save @paytheory/payment-components
Sandbox Install
npm install --save @paytheory/payment-components@sandbox
Live Import
import '@paytheory/payment-components'
or
<script src="https://sdk.paytheory.com"></script>
Sandbox Import
import '@paytheory/payment-components@sandbox'
or
<script src="https://stage.sdk.paytheorystudy.com"></script>
either way the SDK will be exposed as
window.paytheory
Usage
There are ten components available to use for payments.
Credit Card Component
This component will provide a full payment implementation.
codesandbox credit card component example
Credit Card Component provides a single form entry combining:
- credit card number
- credit card CVV security code
- credit card expiration date
Credit Card Component requires a container for the credit card input:
<form>
...
<div id="pay-theory-credit-card"></div>
...
</form>
Credit Card Component cannot be used in combination with:
- Credit Card Number Component
- Credit Card Expiration Component
- Credit Card CVV Component
Credit Card Number, Expiration and CVV Components
These components will provide a full payment implementation.
codesandbox credit card components example
These components must be combined in a form to enable payment:
- Credit Card Number Component
- Credit Card CVV Component
- Credit Card Expiration Component
A container is required for each component:
<form>
...
<div id="pay-theory-credit-card-number"></div>
<div id="pay-theory-credit-card-exp"></div>
<div id="pay-theory-credit-card-cvv"></div>
...
</form>
These components cannot be used in combination with:
- Credit Card Component
Credit Card Account Name & Address Components
codesandbox credit card address fields example
Six optional components are available to capture additional details about the card:
- Credit Card Account Name Component
- Credit Card Address Line 1 Component
- Credit Card Address Line 2 Component
- Credit Card City Component
- Credit Card State Component
- Credit Card Zip Code Component
These entries can be placed wherever you prefer in relation to the other credit card component(s).
Include a container for each of the optional inputs you wish to use:
<form>
...
<div id="pay-theory-credit-card-account-name"></div>
...
<div id="pay-theory-credit-card-address-1"></div>
<div id="pay-theory-credit-card-address-2"></div>
<div id="pay-theory-credit-card-city"></div>
<div id="pay-theory-credit-card-state"></div>
<div id="pay-theory-credit-card-zip"></div>
...
</form>
Styling the container
To style the input container simply provide your own CSS for the pay theory containers you create.
Individual pay-theory-credit-card-number containers should be at least 340px wide, pay-theory-credit-card combined input should be 400px
#pay-theory-credit-card-number,
#pay-theory-credit-card-exp,
#pay-theory-credit-card-cvv {
height: 1.75em;
border: solid 1px #ccc;
border-radius: 5px;
margin: 4px 0;
}
Handle state with callbacks
Mount to create the credit card field(s) and establish callbacks:
// API KEY is required
const API_KEY = 'your-api-key'
// optionally define custom styles for the input components text
const STYLES = {
default: {
color: 'black',
fontSize: '14px'
},
success: {
color: '#5cb85c',
fontSize: '14px'
},
error: {
color: '#d9534f',
fontSize: '14px'
}
}
// optionally provide custom tags to help track purchases
const TAGS = { YOUR_TAG_KEY: 'YOUR_TAG_VALUE' }
/**
* optionally set the fee mode
* by default SURCHARGE mode is used
* SERVICE_FEE mode is available only when enabled by Pay Theory
* SURCHARGE mode applies a fee of 2.9% + $0.30
* to be deducted from original amount
* SERVICE FEE mode calculates a fee based on predetermined parameters
* and adds it to the original amount
**/
const FEE_MODE = window.paytheory.SURCHARGE
// create a place to store the credit card
let myCreditCard
(async() => {
/**
* initialize the SDK (can also be called as a promise)
*
* if providing tags but no styles, provide an empty object
* as a placeholder
**/
myCreditCard = await window.paytheory.create(
API_KEY,
STYLES,
TAGS,
FEE_MODE)
// mount the hosted fields into the container
myCreditCard.mount()
// handle callbacks
myCreditCard.readyObserver(ready => {
/**
* ready is a boolean indicator
* fires when SDK is loaded and ready
* this is where you would associate any listeners
* to trigger initTransaction
* or optionally confirmation
**/
})
// only needed when REQUIRE_CONFIRMATION is true
myCreditCard.tokenizeObserver(tokenized => {
/**
* results of the payment card tokenization
* fires once when tokenization is completed
* this is a good place to enable confirmation
**/
})
// only needed when REQUIRE_CONFIRMATION is true
myCreditCard.captureObserver(transactionResult => {
/**
* results of the transaction with confirmation
* fires once when capture is completed
**/
})
// only needed when REQUIRE_CONFIRMATION is false
myCreditCard.transactedObserver(transactionResult => {
/**
* results of the transaction without confirmation
* fires once when transaction is completed
**/
})
myCreditCard.validObserver(valid => {
/**
* valid is a boolean indicator
* fires every time the valid state of the hosted field changes
* when valid is true is a good time to enable initTransaction
**/
})
myCreditCard.errorObserver(error => {
/**
* error is false or a message
* fires every time the error state/message changes
**/
})
})()
Initiate the transaction
Once the transaction has ended in either success or failure the buyer should be directed to a results page.
When ready submit the transaction using the saved credit card:
// optionally provide details about the buyer
const BUYER_OPTIONS = {
"first_name": "Some",
"last_name": "Body",
"email": "somebody@gmail.com",
"phone": "3335554444",
"personal_address": {
"city": "Somewhere",
"country": "USA",
"region": "OH",
"line1": "123 Street St",
"line2": "Apartment 17",
"postal_code": "12345"
}
}
// optional parameter to require confimation step
const REQUIRE_CONFIRMATION = true
/**
* create a listener that will trigger the payment process
* if REQUIRE_CONFIRMATION is true
* this step will only complete tokenization
* otherwise tokenization and capture observers are bypassed
**/
const clickListener = (e) => {
e.preventDefault()
...
/**
* begin the transaction authorization by providing an amount
* and optionally details about the buyer and a flag for confirmation
* amount must be a positive integer or an error will be thrown
* */
myCreditCard.initTransaction(
AMOUNT,
BUYER_OPTIONS,
REQUIRE_CONFIRMATION // defaults to false
)
}
/**
* optional
* use the tokenObserver to handle confirmation step
**/
myCreditCard.tokenizeObserver((card) => {
const confirmation = `Are you sure you want to make a payment on ${card.brand} card beginning with ${card.first_six}`
if (confirm(confirmation)) {
myCreditCard.confirm();
} else {
myCreditCard.cancel();
}
});
/**
* use the ready observer from above to apply listeners
* provide your own component IDs
**/
myCreditCard.readyObserver(ready => {
...
document
.getComponentById("initiate-payment-button-id")
.addEventListener("click", clickListener)
...
})
Tokenization response
When the confirm option of initTransaction is set to true, the payment card token details are returned in tokenizeObserver
note that the service fee is included in amount
{
"first_six": "XXXXXX",
"brand": "XXXX",
"receipt_number": "pt-dev-XXXXXX",
"amount": 999,
"service_fee": 195
}
Completion response
Upon completion of authorization and capture, details similar to the following are returned:
note that the service fee is included in amount
{
"receipt_number":"pt-env-XXXXXX",
"last_four": "XXXX",
"brand": "XXXXXXXXX",
"created_at":"YYYY-MM-DDTHH:MM:SS.ssZ",
"amount": 999,
"service_fee": 195,
"state":"SUCCEEDED",
"tags":{ "pay-theory-environment":"env","pt-number":"pt-env-XXXXXX", "YOUR_TAG_KEY": "YOUR_TAG_VALUE" }
}
If a failure or decline occurs during the transaction, the response will be similar to the following:
{
"receipt_number":"pt-test-XXXXXX",
"last_four":"XXXX",
"brand":"VISA",
"state":"FAILURE",
"type":"some descriptive reason for the failure / decline"
}
Polyfill and IE 11
To enable IE 11 support you must include the following in your HTML head:
<head>
<!--
you can find the latest versions of these at the following links
https://cdnjs.com/libraries/webcomponentsjs
https://cdnjs.com/libraries/core-js
-->
<!-- begin polyfill -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.6.5/minified.js"
integrity="sha512-il4gs09hawMRQdgVPe9NUODC2gBmQ3lX15lMK1y/WWAkfRRd94yET47NgghJZBSJcPW6ZrqyIziQIT6dI7I3KA=="
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.4.4/webcomponents-bundle.js"
integrity="sha512-bZ7i/n59i3BPUaM+5s7WiMcE3tlVqk9HV4GrpcFfWWhsCYtZa+0MZ4LXl2zhjBsmNGmOOVbjk8WvSNa4wdxYNg=="
crossorigin="anonymous"
></script>
<!-- end polyfill -->
<!-- for sandbox -->
<script src="https://stage.sdk.paytheorystudy.com"></script>
<!-- for live -->
<script src="https://sdk.paytheory.com"></script>
</head>
License
MIT © pay theory