- https://secure.verotel.com
- https://secure.billing.creditcard
- https://secure.gaycharge.com
- https://secure.yoursafedirect.com
Create a purchase order
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
FlexPay purchase call is used to redirect buyer to the Verotel Order Page in order to process the purchase sale.
HTTP request
Verotel
GET https://secure.verotel.com/startorder?
CardBilling
GET https://secure.billing.creditcard/startorder?
GayCharge
GET https://secure.gaycharge.com/startorder?
YoursafeDirect
GET https://secure.yoursafedirect.com/startorder?
NOTE: only EUR is can be used for DDEU payment method system |
NOTE: DDEU is available only in DE, AT, CH, BE, IT, NL, ES and FR
If oneClickToken is sent, the payment method must be set to CC.
When processing without Orderpage, IDEAL must be set. |
NOTE: oneClickToken is excluded from signature calculations |
NOTE: email is excluded from signature calculations (max 100 chars else it will be ignored) |
$brand = Verotel\FlexPay\Brand::create_from_merchant_id(/* Your customer ID */ '9804000000000000');
$flexpayClient = new Verotel\FlexPay\Client(/* shop ID */ 12345, "FlexPay Signature Key", $brand);
$purchaseUrl = $flexpayClient->get_purchase_URL([
"priceAmount" => 2.64,
"priceCurrency" => "EUR",
"description" => "Test purchase",
]);
FlexPayClient flexPayClient = new FlexPayClient(
685478, // shop ID / website ID
"d6dToIj2d6YJ1PX2D1W9", // FlexPay signatureKey
Brand.YOURSAFE_DIRECT
);
URL purchaseUrl = flexPayClient.purchaseBuilder()
.withAmount(BigDecimal.valueOf(14), SaleCurrency.EUR)
.withDescription("Purchase of foo")
.withPaymentMethod(PaymentMethod.IDEAL)
.withEmail("example@example.com")
.withDeclineURL("http://example.com/declined")
.withSuccessURL("http://example.com/back")
.build();
GET https://secure.verotel.com/startorder
?version=4
&shopID=12345
&type=purchase
&priceAmount=9.99
&priceCurrency=USD
&description=Test purchase
&paymentMethod=CC
&referenceID=order-1001
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&successURL=https://example.com/success
&declineURL=https://example.com/declined
&oneClickToken=one-click-token
&email=buyer@example.com
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://secure.verotel.com/startorder");
url.searchParams.set("version", "4");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "purchase");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("description", "Test purchase");
url.searchParams.set("paymentMethod", "CC");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("custom1", "xxyyzz");
url.searchParams.set("custom2", "custom-2");
url.searchParams.set("custom3", "custom-3");
url.searchParams.set("successURL", "https://example.com/success");
url.searchParams.set("declineURL", "https://example.com/declined");
url.searchParams.set("oneClickToken", "one-click-token");
url.searchParams.set("email", "buyer@example.com");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"version": "4",
"shopID": "12345",
"type": "purchase",
"priceAmount": "9.99",
"priceCurrency": "USD",
"description": "Test purchase",
"paymentMethod": "CC",
"referenceID": "order-1001",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"successURL": "https://example.com/success",
"declineURL": "https://example.com/declined",
"oneClickToken": "one-click-token",
"email": "buyer@example.com",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://secure.verotel.com/startorder?" + urlencode(params)
response = urlopen(url)/startorderQuery parameters
versionnumberrequiredversion version of the FlexPay call, 4 for this version
shopIDnumberrequirednumerical ID of the website in the Verotel system
typestringrequiredpurchase
priceAmountnumberrequiredpriceAmount amount to be processed in nnn.nn format
priceCurrencystringrequired- priceCurrency 3 char ISO code, must be one of the Sale currencies (
USDEURGBPAUDCADCHFDKKNOKSEK) - NOTE: only
EURis can be used forDDEUpayment method system
descriptionstringrequireddescription of the product. Text is displayed on the order page - max 100 printable characters
paymentMethodstring- payment method,
CC,YOURSAFE_DIRECTor,DDEU(if not set then buyers can choose from available payment methods) - NOTE:
DDEUis available only in DE, AT, CH, BE, IT, NL, ES and FR - If oneClickToken is sent, the payment method must be set to
CC. - When processing without Orderpage,
IDEALmust be set.
referenceIDstringmerchant’s reference identifier. It must be unique if provided
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
successURLstringURL for redirect after successful transaction - max 255 characters. Defaults to success landing URL on the website.
declineURLstringURL for redirect after declined transaction - max 255 characters. Defaults to decline landing URL on the website.
oneClickTokenstring- the one-time oneClickToken from previous purchase
- NOTE: oneClickToken is excluded from signature calculations
emailstring- email of the buyer. If not set, it will be collected on the Order Page
- NOTE: email is excluded from signature calculations (max 100 chars else it will be ignored)
signaturestringrequiredSignature calculation
Success redirect
After a successful transaction the buyer is redirected to one of these:
The default website Flexpay success URL (Setup in Control Center/Setup Websites/Website detail/FlexPay Options)
The URL set in
successURLFlexpay parameter – overrides the website Flexpay success URL
GET https://example.com/success
?shopID=12345
&type=purchase
&referenceID=order-1001
&saleID=123456
&priceAmount=9.99
&priceCurrency=USD
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&paymentMethod=CC
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://example.com/success");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "purchase");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("custom1", "xxyyzz");
url.searchParams.set("custom2", "custom-2");
url.searchParams.set("custom3", "custom-3");
url.searchParams.set("paymentMethod", "CC");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"shopID": "12345",
"type": "purchase",
"referenceID": "order-1001",
"saleID": "123456",
"priceAmount": "9.99",
"priceCurrency": "USD",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"paymentMethod": "CC",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://example.com/success?" + urlencode(params)
response = urlopen(url)// GET https://example.com/success
$params = [
"shopID" => "12345",
"type" => "purchase",
"referenceID" => "order-1001",
"saleID" => "123456",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"paymentMethod" => "CC",
"signature" => "abcdef0123456789abcdef0123456789abcdef01",
];// GET https://example.com/success
Map<String, String> params = Map.ofEntries(
Map.entry("shopID", "12345"),
Map.entry("type", "purchase"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("paymentMethod", "CC"),
Map.entry("signature", "abcdef0123456789abcdef0123456789abcdef01")
);Your endpoint receives this call.
Query parameters
shopIDnumbernumerical ID of the website in the Verotel system
typestringpurchase
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
priceAmountnumberamount to be processed in nnn.nn format
priceCurrencystring3 char ISO code of the Sale currency
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
paymentMethodstringpayment method, CC, YOURSAFE_DIRECT, DDEU
signaturestringSignature calculation
Postbacks
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
After every sale or transaction based action a corresponding postback is sent to the registered Postback URL.
Postback data are sent as GET request.
Verifying postback
As a security measure postback have to be validated that it contains correctly computed Signature.
Responding to postback
Important: The Verotel system expects HTTP status code 200 and plain text “OK” response. The response must be returned within 30 seconds.
$brand = Verotel\FlexPay\Brand::create_from_merchant_id(/* Your customer ID */ '9804000000000000');
$flexpayClient = new Verotel\FlexPay\Client(/* shop ID */ 12345, "FlexPay Signature Key", $brand);
if (!$flexpayClient->validate_signature($_GET)){
http_response_code(400);
echo "ERROR - Invalid signature!";
exit;
}
// handle correct postback
...
echo "OK";
// pass GET params received in postback
Boolean paramsAreVerified = flexPayClient.validateSignature(Map.of(...));
Success postback
The successful sale postback is sent to the website “Flexpay postback URL” immediately after the sale has been processed. The postback is sent only for successfully approved transactions. The data in the postback provide essential information about the sale. If more information is needed, for example billing address or email address of the buyer, the merchant should query the status page.
Important: The Verotel system expects HTTP status code 200 and plain text “OK” response. The response must be returned within 30 seconds.
GET https://example.com/postback
?shopID=12345
&type=purchase
&referenceID=order-1001
&saleID=123456
&transactionID=987654
&priceAmount=9.99
&priceCurrency=USD
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&paymentMethod=CC
&oneClickToken=one-click-token
&signature=abcdef0123456789abcdef0123456789abcdef01
&truncatedPAN=411111******1111
&CCBrand=VISAconst url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "purchase");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("transactionID", "987654");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("custom1", "xxyyzz");
url.searchParams.set("custom2", "custom-2");
url.searchParams.set("custom3", "custom-3");
url.searchParams.set("paymentMethod", "CC");
url.searchParams.set("oneClickToken", "one-click-token");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
url.searchParams.set("truncatedPAN", "411111******1111");
url.searchParams.set("CCBrand", "VISA");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"shopID": "12345",
"type": "purchase",
"referenceID": "order-1001",
"saleID": "123456",
"transactionID": "987654",
"priceAmount": "9.99",
"priceCurrency": "USD",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"paymentMethod": "CC",
"oneClickToken": "one-click-token",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
"truncatedPAN": "411111******1111",
"CCBrand": "VISA",
}
url = "https://example.com/postback?" + urlencode(params)
response = urlopen(url)// GET https://example.com/postback
$params = [
"shopID" => "12345",
"type" => "purchase",
"referenceID" => "order-1001",
"saleID" => "123456",
"transactionID" => "987654",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"paymentMethod" => "CC",
"oneClickToken" => "one-click-token",
"signature" => "abcdef0123456789abcdef0123456789abcdef01",
"truncatedPAN" => "411111******1111",
"CCBrand" => "VISA",
];// GET https://example.com/postback
Map<String, String> params = Map.ofEntries(
Map.entry("shopID", "12345"),
Map.entry("type", "purchase"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("transactionID", "987654"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("paymentMethod", "CC"),
Map.entry("oneClickToken", "one-click-token"),
Map.entry("signature", "abcdef0123456789abcdef0123456789abcdef01"),
Map.entry("truncatedPAN", "411111******1111"),
Map.entry("CCBrand", "VISA")
);Your endpoint receives this call.
Query parameters
shopIDnumbernumerical ID of the website in the Verotel system
typestringpurchase
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
transactionIDnumberidentifier of the transaction in the Verotel system (only avaible for postbacks version 2)
priceAmountnumberamount to be processed in nnn.nn format
priceCurrencystring3 char ISO code of the Sale currency
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
paymentMethodstringpayment method, CC, YOURSAFE_DIRECT, DDEU
oneClickTokenstringif the feature is enabled - oneClickToken valid for next purchase
signaturestringSignature calculation
truncatedPANstringTruncated (masked) payment instrument identification, e.g. card number
CCBrandstringOnly present if paid via Credit Card, represents the card brand, e.g. VISA
Credit postback
Credit postback call is sent to the merchant’s postback URL when the sale transaction is credited by merchant, Verotel support or by system (e.g. when an automated refund is performed).
GET https://example.com/postback
?shopID=12345
&event=credit
&referenceID=order-1001
&saleID=123456
&priceAmount=9.99
&priceCurrency=USD
&transactionID=987654
&parentID=456789
&type=purchase
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("event", "credit");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("transactionID", "987654");
url.searchParams.set("parentID", "456789");
url.searchParams.set("type", "purchase");
url.searchParams.set("custom1", "xxyyzz");
url.searchParams.set("custom2", "custom-2");
url.searchParams.set("custom3", "custom-3");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"shopID": "12345",
"event": "credit",
"referenceID": "order-1001",
"saleID": "123456",
"priceAmount": "9.99",
"priceCurrency": "USD",
"transactionID": "987654",
"parentID": "456789",
"type": "purchase",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://example.com/postback?" + urlencode(params)
response = urlopen(url)// GET https://example.com/postback
$params = [
"shopID" => "12345",
"event" => "credit",
"referenceID" => "order-1001",
"saleID" => "123456",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"transactionID" => "987654",
"parentID" => "456789",
"type" => "purchase",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"signature" => "abcdef0123456789abcdef0123456789abcdef01",
];// GET https://example.com/postback
Map<String, String> params = Map.ofEntries(
Map.entry("shopID", "12345"),
Map.entry("event", "credit"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("transactionID", "987654"),
Map.entry("parentID", "456789"),
Map.entry("type", "purchase"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("signature", "abcdef0123456789abcdef0123456789abcdef01")
);Your endpoint receives this call.
Query parameters
shopIDnumbernumerical ID of the website in the Verotel system
eventstringcredit
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
priceAmountnumberamount of refunded transaction
priceCurrencystringrefunded transaction currency
transactionIDnumbertransaction id of credit transaction
parentIDnumbertransaction id of transaction which was credited
typestringpurchase
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Chargeback postback
Chargeback postback call is sent to the merchant’s postback URL when sale transaction is chargebacked. This also blacklists the buyer.
GET https://example.com/postback
?shopID=12345
&event=chargeback
&referenceID=order-1001
&saleID=123456
&priceAmount=9.99
&priceCurrency=USD
&transactionID=987654
&parentID=456789
&type=purchase
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("event", "chargeback");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("transactionID", "987654");
url.searchParams.set("parentID", "456789");
url.searchParams.set("type", "purchase");
url.searchParams.set("custom1", "xxyyzz");
url.searchParams.set("custom2", "custom-2");
url.searchParams.set("custom3", "custom-3");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"shopID": "12345",
"event": "chargeback",
"referenceID": "order-1001",
"saleID": "123456",
"priceAmount": "9.99",
"priceCurrency": "USD",
"transactionID": "987654",
"parentID": "456789",
"type": "purchase",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://example.com/postback?" + urlencode(params)
response = urlopen(url)// GET https://example.com/postback
$params = [
"shopID" => "12345",
"event" => "chargeback",
"referenceID" => "order-1001",
"saleID" => "123456",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"transactionID" => "987654",
"parentID" => "456789",
"type" => "purchase",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"signature" => "abcdef0123456789abcdef0123456789abcdef01",
];// GET https://example.com/postback
Map<String, String> params = Map.ofEntries(
Map.entry("shopID", "12345"),
Map.entry("event", "chargeback"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("transactionID", "987654"),
Map.entry("parentID", "456789"),
Map.entry("type", "purchase"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("signature", "abcdef0123456789abcdef0123456789abcdef01")
);Your endpoint receives this call.
Query parameters
shopIDnumbernumerical ID of the website in the Verotel system
eventstringchargeback
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
priceAmountnumberamount of chargebacked transaction
priceCurrencystringchargebacked transaction currency
transactionIDnumbertransaction id of credit transaction
parentIDnumbertransaction id of transaction which was credited
typestringpurchase
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Status page request
A status of a sale made with a FlexPay API can be reviewed by querying the status page. Status page provides complete information about the sale, the buyer, and its status.
HTTP request
Verotel
GET https://secure.verotel.com/status/order?
CardBilling
GET https://secure.billing.creditcard/status/order?
GayCharge
GET https://secure.gaycharge.com/status/order?
YoursafeDirect
GET https://secure.yoursafedirect.com/status/order?
NOTFOUND - purchase not found
ERROR - error (see ‘error’ key) |
Can be one of following: Credit Card or Direct Debit EU |
$brand = Verotel\FlexPay\Brand::create_from_merchant_id(/* Your customer ID */ '9804000000000000');
$flexpayClient = new Verotel\FlexPay\Client(/* shop ID */ 12345, "FlexPay Signature Key", $brand);
$statusURL = $flexpayClient->get_status_URL(['saleID' => 123456]);
$statusPageData = Symfony\Component\Yaml\Yaml::parse(file_get_contents($statusURL));
// handle data fetched from status page
URL statusUrl = flexPayClient.getStatusUrlBySale(1234);
GET https://secure.verotel.com/status/order
?version=4
&shopID=12345
&referenceID=order-1001
&saleID=123456
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://secure.verotel.com/status/order");
url.searchParams.set("version", "4");
url.searchParams.set("shopID", "12345");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"version": "4",
"shopID": "12345",
"referenceID": "order-1001",
"saleID": "123456",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://secure.verotel.com/status/order?" + urlencode(params)
response = urlopen(url)/status/orderQuery parameters
versionnumber4
shopIDnumbernumerical ID of the website in the Verotel system
referenceIDstringMerchant’s reference identifier if provided (referenceID OR saleID must be posted - NOT BOTH)
saleIDnumberVerotel saleID identifier (referenceID OR saleID must be posted - NOT BOTH)
signaturestringSignature calculation
Response
200responsestringFOUND- purchase record found and returnedNOTFOUND- purchase not foundERROR- error (see ‘error’ key)
errorstringmessage (for response=ERROR)
saleIDstringidentifier of the transaction in Verotel System
shopIDstringID of website in Verotel system
paymentMethodstring- an identifier of payment method that was used for the transaction.
- Can be one of following:
Credit CardorDirect Debit EU
priceAmountstringamount processed. in nnn.nn formatt
priceCurrencystring3 char ISO code of the Sale currency
descriptionstringProduct description text - max 100 printable characters
referenceIDstringMerchant reference identifier - max 100 printable characters
namestringname of the buyer
emailstringemail address of the buyer
countrystringselected or detected country ISO code (ISO 3166-1-alpha-2 code)
oneClickTokenstringIf the feature is enabled - Currently valid oneClickToken
createdOnstringTimestamp of purchase creation
saleResultstringpurchase processing result (APPROVED)
billingAddr_fullNamestringbilling address: full name field value
billingAddr_companystringbilling address: company field value
billingAddr_addressLine1stringbilling address: 1st line field value
billingAddr_addressLine2stringbilling address: 2nd line field value
billingAddr_citystringbilling address: city name
billingAddr_zipstringbilling address: zip code / postal code
billingAddr_statestringbilling address: US state code (ISO 3166-2)
billingAddr_countrystringbilling address: country ISO code (ISO 3166-1-alpha-2 code)
One Click Purchase
The One Click functionality allows buyers to pay instantly without any type of confirmation. The instant One Click will try to charge their previously saved credit card without the need to re-enter the CVV code or any other additional information. This allows the FlexPay purchase sales to be processed quickly without distracting the buyer unnecessarily.
Security
The One Click functionality has been designed to be as secure as possible to minimize any risks of misuse and to protect both merchants and buyers alike. The same fraud prevention measures apply as per standard Order Page interactions.
Enabling the One Click
The One Click feature is disabled by default and is a subject of approval by Verotel. Please contact merchantsupport@verotel.com to enquire. This document assumes the feature is enabled.
Limitations
- In case the Order Page requires the buyers to enter their billing address, the full order page is displayed.
Interaction
Initial sale
In order to charge the buyer again with One Click the “oneClickToken” is required.
The token is generated with the first successful sale (normal FlexPay purchase sale with full Order Page interaction initiated by “purchase order” request) when the buyer chooses to “Remember my card for future purchases”.
The Successful sale postback returns the “oneClickToken” to merchant’s system.
One Click sale
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
To perform a One Click sale, the currently active token has to be included in the next “purchase order“ request.
If the token is valid, the “purchase order” request is processed without any further buyer interaction.
If the order is approved, the buyer receives a standard receipt email, an approval page is displayed and the buyer is redirected to one of these:
The default website Flexpay success URL (Setup in Control Center/Setup Websites/Website detail/FlexPay Options)
The URL set in successURL Flexpay parameter – overrides the website Flexpay success URL
The new valid “oneClickToken” is passed with the Successful sale postback call to the merchant’s system for use in the next sale.
$brand = Verotel\FlexPay\Brand::create_from_merchant_id(/* Your customer ID */ '9804000000000000');
$flexpayClient = new Verotel\FlexPay\Client(/* shop ID */ 12345, "FlexPay Signature Key", $brand);
$purchaseUrl = $flexpayClient->get_purchase_URL([
"priceAmount" => 2.64,
"priceCurrency" => "EUR",
"description" => "Test purchase",
"oneClickToken" => "1FD5F342-48DB-11E6-B445-A19150BFB283"
]);
URL purchaseUrl = flexPayClient.purchaseBuilder()
.withAmount(BigDecimal.valueOf(14), SaleCurrency.EUR)
.withDescription("Purchase of foo")
.withPaymentMethod(PaymentMethod.IDEAL)
.withEmail("example@example.com")
.withDeclineURL("http://example.com/declined")
.withSuccessURL("http://example.com/back")
.withOneClickToken("foo-token")
.build();
Validity of the oneClickToken
The “oneClickToken” can be only be used once. It is invalidated in case the transaction is either approved or declined.
This means that the merchant’s system has to manage storage and update the active tokens for users upon receiving Successful sale postback calls but also in case of declines. A user can be identified by e.g. custom1-3 fields or referenceID passed by the merchant’s system in the “purchase order” request and returned in the Successful sale postback.
The “oneClickToken” expires automatically after 30 days. The buyer will need to enter CVV code to generate a new one and to resume the One Click functionality.
The “oneClickToken” is linked to a website and to the buyer’s remembered card information stored in the form of a cookie in the browser.
This means that:
the token is not valid for other websites
the token will not work in case the buyer uses a different browser
the token expires if the buyer chooses to forget the stored card
Signature calculation
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
If you are using one of our client libraries, signature calculation is handled by the library.
The signature used in FlexPay requests and postbacks is calculated as SHA-256 hash (hexadecimal output) from the request parameters.
The first parameter has to be your signatureKey, followed by the parameters ordered alphabetically by their names.
Optional arguments that are used (have value) must be contained in the signature calculation. Optional arguments that are not used must not be contained in the signature calculation.
The email parameter in “startorder” request is not included in the signature calculations.
It is mandatory to convert arguments values into UTF-8 before computing the signature.
$brand = Verotel\FlexPay\Brand::create_from_merchant_id(/* Your customer ID */ '9804000000000000');
$flexpayClient = new Verotel\FlexPay\Client(/* shop ID */ 12345, "FlexPay Signature Key", $brand);
$computed_signature = $flexpayClient->get_signature([
'description' => 'Super video download',
'priceAmount' => '9.99',
'priceCurrency' => 'USD',
'shopID' => 12345,
'version' => 4,
]);
String computedSignature = flexpayClient.getSignature(Map.of(
"description", "Super video download",
"priceAmount", "9.99",
"priceCurrency", "USD",
"shopID", 12345,
"version", 4
));
Example calculation
| Parameter | Value |
|---|---|
| (signatureKey) | BddJxtUBkDgFB9kj7Zwguxde4gAqha |
| description | Super video download |
| priceAmount | 9.99 |
| priceCurrency | USD |
| custom1 | xxyyzz |
| shopID | 64233 |
| type | purchase |
| version | 4 |
signature = sha256_hex(BddJxtUBkDgFB9kj7Zwguxde4gAqha:custom1=xxyyzz:description=Super video download:priceAmount=9.99:priceCurrency=USD:shopID=64233:type=purchase:version=4) => ccaf2357fe330654322a1b0f3f92984b3fe2a1462d6fc5082650a00c5ada2f2a
https://secure.verotel.com/startorder?custom1=xxyyzz&description=Super+video+download&priceAmount=9.99&priceCurrency=USD&shopID=64233&type=purchase&version=4&signature=ccaf2357fe330654322a1b0f3f92984b3fe2a1462d6fc5082650a00c5ada2f2a
Payment processor
| Processor name | Allowed payment method | Base URL |
|---|---|---|
| Verotel | CCDDEU | https://secure.verotel.com/ |
| CardBilling | CC | https://secure.billing.creditcard/ |
| GayCharge | CCDDEU | https://secure.gaycharge.com/ |
| YoursafeDirect | DDEUYOURSAFE_DIRECT | https://secure.yoursafedirect.com/ |