InCountry Payment Gateway Documentation
Payment Gateway is a solution which allows you to securely store credit cards and use their data to perform transactions against different payment gateways and third party API’s. It provides both the credit card tokenization and data vault for being PCI DSS compliant without implementing any additional solutions on your side. Tokenized payment methods are stored in the InCountry Platform allowing you to separately store card data and then pass it to different payment providers depending on your business requirements.
Overview
The entire data flow is shown in the following diagram.
How the saving of credit card data works
- You integrate InCountry JavaScript SDK into your application.
- This JavaScript SDK renders a payment form which is shown to users and visitors when they want to purchase your services or products.
- The payment form through the JavaScript SDK passes the credit card data to InCountry Border.
- InCountry Border writes the credit card data to the InCountry Platform.
- The InCountry Platform returns the tokenized data (instead of the credit card data) to InCountry Border.
- InCountry Border passes this tokenized data (credit card data) to the backend of your application.
- Your application backend saves this tokenized data to the application database along with the identification token for this user.
- Your application backend provides the tokenized data to its frontend when needed.
How the payment is performed
- Your application frontend requests information about a specific credit card from its backend.
- Your application backend initiates a request to the payment provides through InCountry Border against the identification token associated with the user.
- InCountry Border requests the credit card data (unredacted) from the InCountry Platform.
- InCountry Border provides the credit card data to the payment provider.
Getting started with Payment Gateway
The generic workflow to get started with Payment Gateway includes the following:
- Creating a user account in InCountry Platform.
- Creating an environment and credentials to access it. By default, the InCountry team will create them on your behalf.
- Creating a payment form.
- Taking the payment information.
- Submitting the payment form.
Integrating the payment form
The storing of PCI DSS data along with the collection of this data should be performed in a secure way. InCountry provides the JavaScript SDK which allows you to create payment forms and securely collect payment data.
The generic workflow is comprised of the following steps:
Include the script on each page of your website. It should always be loaded directly from the InCountry endpoint, rather than included within an application bundle or hosted yourself. Please request the address of the endpoint from the InCountry team.
<script src="{INCOUNTRY_ENDPOINT}"></script> // PLEASE REQUEST THE ACTUAL {INCOUNTRY_ENDPOINTS} FROM THE INCOUNTRY TEAM.
Create an HTML form to collect the payment data:
//THIS IS AN EXAMPLE OF A FORM TO COLLECT CREDIT CARD DATA. //YOUR FINAL SOLUTION AND ITS DESIGN MAY VARY <form id="x-payment-form"> <div id="x-card-number"></div> <div id="x-card-expiry"></div> <div id="x-card-cvc"></div> <button type="submit">Pay</button> </form>
Use
InCountry(borderUrl)
to create an instance of the InCountry object. This object will be used as your entry point to the rest of the SDK.warning
InCountry Border will be configured for you by InCountry team.
var incountry = InCountry('{INCOUNTRY_BORDER_URL}'); // PLEASE REQUEST THE CORRECT INCOUNTRY_BORDER_URL FROM THE INCOUNTRY TEAM.
Create an
Elements
instance which manages a group of elements.var elements = incountry.elements();
Create instances of specific
Elements
. It takes thetype
ofElement
to create. For the payment form, you should create a card number, card expiration, and card security code instances.var cardNumberElement = elements.create('cardNumber'); var cardExpiryElement = elements.create('cardExpiry'); var cardCvcElement = elements.create('cardCvc');
Integrate elements into the DOM.
cardNumberElement.mount('#x-card-number'); cardExpiryElement.mount('#x-card-expiry'); cardCvcElement.mount('#x-card-cvc');
The payment form is ready to go.
Submitting the payment form
Use elements.redact(callback)
to redact information collected by card elements (input fields) that you safely pass to your server to use in a Stripe API call.
// Submits all of the form fields by executing a POST request.
document
.getElementById('x-payment-form')
.addEventListener('submit', e => {
e.preventDefault();
elements.redact(redactedCard => {
fetch('https://your.server.io/buy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(redactedCard),
})
.then(response => response.json())
.then(data => {
if (data.message) {
// some actions here...
// ...
// If 3ds flow
if (data.redirect_url) {
window.location.href = data.redirect_url;
}
}
});
});
Once elements.redact(redactedCard)
has been called, the request goes through InCountry Border which redacts the card data. Then the request with redacted card data comes to your server to the POST /cards
endpoint. On your server you can link the redacted card data to a specific user, etc. the POST /cards
method should return a unique entityId
and all the redacted fields in the JSON response.
Then you can pass redactedCard
to your server. In our example above we do a request to https://your.server.io/buy
.
Using Stripe API with redacted card data
In your server’s POST /buy
handler you should send all requests to Stripe through InCountry Border. For example in Node.js using axios:
const axios = require('axios');
const querystring = require('querystring');
app.post('/buy', async function(req, res) {
const entityId = req.body.x-inc-entityId
// In this stage the data is redacted and it will be unredacted via the InCountry Border Proxy
const redactedCardNumber = req.body.cardNumber
const redactedCardExpMonth = req.body.cardExpMonth
const redactedCardExpYear = req.body.cardExpYear
const redactedCardCvc = req.body.cardCvc
const a = axios.create({
baseURL: `${INCOUNTRY_BORDER_URL}`,
headers: {
'Authorization': `Bearer ${STRIPE_SECRET_KEY}`,
'Content-Type': 'application/x-www-form-urlencoded',
}
});
// Here the request to Stripe will go via InCountry Border Proxy.
const token = await a.post('tokens', querystring.stringify({
entityId: x-inc-entityId,
'card[number]': redactedCardNumber,
'card[exp_month]': redactedCardExpMonth,
'card[exp_year]': redactedCardExpYear,
'card[cvc]': redactedCardCvc,
}));
// some more actions
// ...
});
The request to the /tokens
endpoint will go through InCountry Border which will unredact the redacted card data and pass it to Stripe for performing the payment transaction.