Save a token to capture future payments
While most e-commerce businesses handle one-off payments, you might need to
ask for a customer’s card and capture payments on it in the future (one, but
also several if needed). This is done by tokenizing the card token created
by ProcessOut.js
↗.
Step 1: Create a customer
Because tokens are specifically linked to one of your customers, you must first
create a Customer
↗ resource.
You can create any number of customer you may need. A customer object may be entirely empty, but we strongly advise you to fill the object with as much data as you have. This can help doing searches on your dashboard, but it also greatly helps us when smart routing transactions related to this customer and decreases fraud risks. You can find all the available Customer attributes here ↗.
The ID of the newly created customer should also be stored in your application or database so you can use it later.
curl -X POST https://api.processout.com/customers \
-u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB \
-d first_name=John \
-d last_name=Smith \
-d currency=USD
var ProcessOut = require("processout");
var client = new ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
var customer = client.newCustomer().create({
first_name: "John",
last_name: "Smith",
currency: "USD"
}).then(function(customer) {
//
}, function(err) {
// An error occured
});
import processout
client = processout.ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
customer = client.new_customer().create({
"first_name": "John",
"last_name": "Smith",
"currency": "USD"
})
require "processout"
client = ProcessOut::Client.new(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
customer = client.customer.create(
first_name: "John",
last_name: "Smith",
currency: "USD"
)
<?php
$client = new \ProcessOut\ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
$customer = $client->newCustomer()->create(array(
"first_name" => "John",
"last_name" => "Smith",
"currency" => "USD"
));
import "github.com/processout/processout-go"
var client = processout.New(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB",
)
cust, err := client.NewCustomer().Create(processout.CustomerCreateParameters{
Customer: &processout.Customer{
FirstName: processout.String("John"),
LastName: processout.String("Smith"),
Currency: processout.String("USD"),
},
})
Note: While the currency field is also optionnal, it will be automatically set to the currency of the first invoice your customer will pay. It is also immutable.
Step 2: Create a customer token
Now that we have a customer object to work with, we can create tokens that’ll
belong to it. Customer tokens can be created from the ones returned by
ProcessOut.js
↗ or by our mobile SDKs ↗
and can be used any number of time.
You have two ways of creating a Customer Token:
- without verifying its source; or
- by verifying its source while creating the Customer Token, which will make the creation fail if the source is invalid (such as an invalid card).
curl -X POST https://api.processout.com/customers/cust_WtaVdUjAGpOlbLiYWYXBR67whr91Rlks/tokens \
-u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB \
-d source=card_Tpu6ZOCDu1tnDKp0kTnPOcVDMUbW7dTU
var ProcessOut = require("processout");
var client = new ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
client.newToken().create({
customer_id: "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
source: "card_Tpu6ZOCDu1tnDKp0kTnPOcVDMUbW7dTU"
}).then(function(token) {
//
}, function(err) {
// An error occured
});
import processout
client = processout.ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
token = client.new_token().create({
"customer_id": "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
"source": "card_Tpu6ZOCDu1tnDKp0kTnPOcVDMUbW7dTU"
})
require "processout"
client = ProcessOut::Client.new(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
token = client.token.create(
customer_id: "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
source: "card_Tpu6ZOCDu1tnDKp0kTnPOcVDMUbW7dTU"
)
<?php
$client = new \ProcessOut\ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
$token = $client->newToken()->create(array(
"customer_id" => "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
"source" => "card_Tpu6ZOCDu1tnDKp0kTnPOcVDMUbW7dTU"
));
import "github.com/processout/processout-go"
var client = processout.New(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB",
)
token, err := client.NewToken().Create(&processout.TokenCreateParameters{
Token: &processout.Token{
CustomerID: processout.String("cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj"),
},
Source: "card_Tpu6ZOCDu1tnDKp0kTnPOcVDMUbW7dTU",
})
curl -X POST https://api.processout.com/customers/cust_WtaVdUjAGpOlbLiYWYXBR67whr91Rlks/tokens \
-u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB \
-d verify=true
var ProcessOut = require("processout");
var client = new ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
client.newToken().create({
customer_id: "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
verify: true
}).then(function(token) {
//
}, function(err) {
// An error occured
});
import processout
client = processout.ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
token = client.new_token().create({
"customer_id": "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
"verify": True
})
require "processout"
client = ProcessOut::Client.new(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
token = client.token.create(
customer_id: "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
verify: true
)
<?php
$client = new \ProcessOut\ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
$token = $client->newToken()->create(array(
"customer_id" => "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
"verify" => true
));
import "github.com/processout/processout-go"
var client = processout.New(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB",
)
token, err := client.NewToken().Create(&processout.TokenCreateParameters{
Token: &processout.Token{
CustomerID: processout.String("cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj"),
},
Verify: true,
})
Note the difference: when not doing any verification, you will send the source
in the Customer Token creation call directly, directly from your backend. Once
you have created the Customer Token without verification, it may be used to
attempt payments directly: jump to Step 4: Capture a payment using the customer token ↗.
If you rather want to operate a verification of the token, you must not send
the source
yourself but rather set the verify
flag.
Step 2.b: Verify Customer Token from front-end
Now that a Customer Token is created, it still is in a pending state and
awaits an actual payment source
to be assigned to it. Such payment source can
for example be a Card
. To link one, send the Customer Token ID to your
front-end.
// Make sure the card ID, customer ID and token ID are available
// in your makeCardToken scope
client.makeCardToken(
"card_1jSEVrx7oaRta1KEdxoMWbiGkK2MijrZ",
"cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
"tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy",
{
// If you want to offer the customer a preferred scheme
// to pay on (for example, if the customer's card supports
// co-schemes such as carte bancaire)
preferred_scheme: "carte bancaire"
}, function(customerTokenID) {
var field = document.createElement("input");
field.type = "hidden";
field.name = "customer_token_id";
field.value = customerTokenID;
// Enable back the button
document.getElementById("paymentBtn").disabled = false;
// We add the customer_token_id input so that it’s sent back to the server.
// The only thing left to do is to submit the form
formElement.appendChild(field);
formElement.submit();
}, function(err) {
document.getElementById("errors").innerHTML = err.message;
});
// Make sure the card ID, customer ID and token ID are available
// in your makeCardToken scope
var tokenRequest = TokenRequest(
source: "card_1jSEVrx7oaRta1KEdxoMWbiGkK2MijrZ",
customerID: "cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj",
tokenID: "tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy"
);
// optional
tokenRequest.thirdPartySDKVersion = ThreeDS2Service.ADY3DS2SDKVersion()
tokenRequest.preferredScheme = "carte bancaire"
ProcessOut.makeCardToken(
tokenRequest,
handler,
with: self
);
// Make sure the card ID, customer ID and token ID are available
// in your makeCardToken scope
TokenRequest tokenRequest = new TokenRequest(
"tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy", // tokenID
"cust_C4hZXQTU0aWoYeenHYC0DektYDqf8ocj", // customerID
"card_1jSEVrx7oaRta1KEdxoMWbiGkK2MijrZ" // source
);
// optional
tokenRequest.setThirdPartySDKVersion(ThreeDS2Service.getSDKVersion())
tokenRequest.setPreferredScheme("carte bancaire")
client.makeCardToken(
tokenRequest,
handler
);
The status of the verification will be denoted in the verification_status
response field↗. The status can have the following values: success
, pending
, failed
, not-requested
and unknown
.
Step 3: Capture a payment using the customer token
After having created a customer token, it is possible to use it to capture any
invoice of any amount at any given time. Simply pass along the Customer Token ID
as the source
when authorizing or capturing a transaction.
curl -X POST https://api.processout.com/invoices/iv_lEZFFcQg5WwpKcolBrlzioeeFnnuPmyE/capture \
-u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB \
-d source=tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy
var ProcessOut = require("processout");
var client = new ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
invoice.capture("tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy").then(
function(transaction) {
//
}, function(err) {
// The invoice could not be captured
});
import processout
client = processout.ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
transaction = invoice.capture("tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy")
require "processout"
client = ProcessOut::Client.new(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
transaction = invoice.capture("tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy")
<?php
$client = new \ProcessOut\ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
$transaction = $invoice->capture("tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy");
import "github.com/processout/processout-go"
var client = processout.New(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB",
)
tr, _ := iv.Capture("tok_fKK4btSG7wd13ZZaevzhMcuNbpjcu1Zy")
Listing and deleting customers’ tokens
Once you’ve stored a token for a customer, you might want to list them so you can show them to your customers, or delete them when your customers want to remove the payment method.
curl -X GET https://api.processout.com/customers/cust_WtaVdUjAGpOlbLiYWYXBR67whr91Rlks/tokens \
-u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB
var ProcessOut = require("processout");
var client = new ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
customer.fetchTokens().then(
function(tokens) {
// And let's say our customer wants to remove its first token
tokens[0].delete();
}, function(err) {
// The customer's tokens could not be fetched
});
import processout
client = processout.ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
tokens = customer.fetch_tokens()
# And let's say our customer wants to remove its first token
tokens[0].delete()
require "processout"
client = ProcessOut::Client.new(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")
tokens = customer.fetch_tokens()
# And let's say our customer wants to remove its first token
tokens.first.delete
<?php
$client = new \ProcessOut\ProcessOut(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");
$tokens = $customer->fetchTokens();
// And let's say our customer wants to remove its first token
$tokens[0]->delete();
import "github.com/processout/processout-go"
var client = processout.New(
"test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
"key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB",
)
tok, _ := cust.FetchTokens()
// And let's say our customer wants to remove its first token
tok.Get().Delete()