- https://secure.verotel.com
- https://secure.billing.creditcard
- https://secure.gaycharge.com
- https://secure.yoursafedirect.com
Create a subscription order
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
The “startorder” subscription request is used to redirect buyer to the Verotel Order Page to process subscription with a given amount, duration and currency.
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?
When processing without Orderpage, at least version 3.3 must be used. |
NOTE: only EUR is can be used for DDEU payment method system |
NOTE: DDEU and YOURSAFE_DIRECT only support one-time |
recurring only | amount to be processed in nnn.nn format for the initial trial period, minimum is 2 days |
recurring only | duration in ISO8601 format, for example: P30D |
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: 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);
$subscriptionUrl = $flexpayClient->get_subscription_URL([
"subscriptionType" => "recurring",
"name" => "Test subscription",
"trialAmount" => 5,
"trialPeriod" => 'P7D',
"priceAmount" => 12.64,
"priceCurrency" => "EUR",
"period" => 'P30D',
]);
URL purchaseUrl = flexPayClient.subscriptionBuilder()
.withAmount("14".toBigDecimal(), SaleCurrency.EUR)
.withDescription("test description")
.withPaymentMethod(PaymentMethod.CC)
.withSubscriptionType(SubscriptionType.recurring)
.withPeriod("P10D")
.build();
GET https://secure.verotel.com/startorder
?version=4
&shopID=12345
&type=subscription
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&subscriptionType=recurring
&trialAmount=5.00
&trialPeriod=P7D
&name=Test subscription
&paymentMethod=CC
&referenceID=order-1001
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&successURL=https://example.com/success
&declineURL=https://example.com/declined
&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", "subscription");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("period", "P30D");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("trialAmount", "5.00");
url.searchParams.set("trialPeriod", "P7D");
url.searchParams.set("name", "Test subscription");
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("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": "subscription",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"subscriptionType": "recurring",
"trialAmount": "5.00",
"trialPeriod": "P7D",
"name": "Test subscription",
"paymentMethod": "CC",
"referenceID": "order-1001",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"successURL": "https://example.com/success",
"declineURL": "https://example.com/declined",
"email": "buyer@example.com",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://secure.verotel.com/startorder?" + urlencode(params)
response = urlopen(url)/startorderQuery parameters
versionnumberrequired- version version of the FlexPay call,
4for this version. - When processing without Orderpage, at least version 3.3 must be used.
shopIDnumberrequirednumerical ID of the website in the Verotel system
typestringrequiredsubscription
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
periodstringrequiredduration in ISO8601 format, for example: P30D, minimum is 7 days for recurring and 2 days for on-time
subscriptionTypestringrequiredone-timeorrecurring- NOTE:
DDEUandYOURSAFE_DIRECTonly supportone-time
trialAmountnumberamount to be processed in nnn.nn format for the initial trial period, minimum is 2 days
trialPeriodstringduration in ISO8601 format, for example: P30D
namestringdescription of the product. Text is displayed on the order page - max 100 printable characters
paymentMethodstring- payment method,
CC,YOURSAFE_DIRECTorDDEU(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.
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=subscription
&subscriptionType=recurring
&event=initial
&referenceID=order-1001
&saleID=123456
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&trialAmount=5.00
&trialPeriod=P7D
&expiresOn or nextChargeOn=value
&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", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "initial");
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("period", "P30D");
url.searchParams.set("trialAmount", "5.00");
url.searchParams.set("trialPeriod", "P7D");
url.searchParams.set("expiresOn or nextChargeOn", "value");
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": "subscription",
"subscriptionType": "recurring",
"event": "initial",
"referenceID": "order-1001",
"saleID": "123456",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"trialAmount": "5.00",
"trialPeriod": "P7D",
"expiresOn or nextChargeOn": "value",
"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" => "subscription",
"subscriptionType" => "recurring",
"event" => "initial",
"referenceID" => "order-1001",
"saleID" => "123456",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"period" => "P30D",
"trialAmount" => "5.00",
"trialPeriod" => "P7D",
"expiresOn or nextChargeOn" => "value",
"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", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "initial"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("period", "P30D"),
Map.entry("trialAmount", "5.00"),
Map.entry("trialPeriod", "P7D"),
Map.entry("expiresOn or nextChargeOn", "value"),
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
typestringsubscription
subscriptionTypestringone-time or recurring
eventstringinitial
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
periodstringsubscription duration in ISO8601 format
trialAmountnumberamount to be processed (max 2 decimal places, stripped zeroes) for the initial trial period
trialPeriodstringduration in ISO8601 format
expiresOn or nextChargeOnstringdate of next rebill or expiry date [yyyy-mm-dd] eq. “2015-04-24”
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(...));
Initial postback
The initial 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=subscription
&subscriptionType=recurring
&event=initial
&referenceID=order-1001
&saleID=123456
&transactionID=987654
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&trialAmount=5.00
&trialPeriod=P7D
&expiresOn or nextChargeOn=value
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&paymentMethod=CC
&signature=abcdef0123456789abcdef0123456789abcdef01
&truncatedPAN=411111******1111
&CCBrand=VISAconst url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "initial");
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("period", "P30D");
url.searchParams.set("trialAmount", "5.00");
url.searchParams.set("trialPeriod", "P7D");
url.searchParams.set("expiresOn or nextChargeOn", "value");
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");
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": "subscription",
"subscriptionType": "recurring",
"event": "initial",
"referenceID": "order-1001",
"saleID": "123456",
"transactionID": "987654",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"trialAmount": "5.00",
"trialPeriod": "P7D",
"expiresOn or nextChargeOn": "value",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"paymentMethod": "CC",
"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" => "subscription",
"subscriptionType" => "recurring",
"event" => "initial",
"referenceID" => "order-1001",
"saleID" => "123456",
"transactionID" => "987654",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"period" => "P30D",
"trialAmount" => "5.00",
"trialPeriod" => "P7D",
"expiresOn or nextChargeOn" => "value",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"paymentMethod" => "CC",
"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", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "initial"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("transactionID", "987654"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("period", "P30D"),
Map.entry("trialAmount", "5.00"),
Map.entry("trialPeriod", "P7D"),
Map.entry("expiresOn or nextChargeOn", "value"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("paymentMethod", "CC"),
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
typestringsubscription
subscriptionTypestringone-time or recurring
eventstringinitial
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
periodstringsubscription duration in ISO8601 format
trialAmountnumberamount to be processed (max 2 decimal places, stripped zeroes) for the initial trial period
trialPeriodstringduration in ISO8601 format
expiresOn or nextChargeOnstringdate of next rebill or expiry date [yyyy-mm-dd] eq. “2015-04-24”
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
truncatedPANstringTruncated (masked) payment instrument identification, e.g. card number
CCBrandstringOnly present if paid via Credit Card, represents the card brand, e.g. VISA
Rebill postback
Rebill postback call is sent to the merchant’s URL immediately after a successful rebill transaction.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=rebill
&referenceID=order-1001
&saleID=123456
&transactionID=987654
&amount=9.99
¤cy=USD
&nextChargeOn=2015-04-24
&subscriptionPhase=terminated
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&paymentMethod=CC
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "rebill");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("transactionID", "987654");
url.searchParams.set("amount", "9.99");
url.searchParams.set("currency", "USD");
url.searchParams.set("nextChargeOn", "2015-04-24");
url.searchParams.set("subscriptionPhase", "terminated");
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": "subscription",
"subscriptionType": "recurring",
"event": "rebill",
"referenceID": "order-1001",
"saleID": "123456",
"transactionID": "987654",
"amount": "9.99",
"currency": "USD",
"nextChargeOn": "2015-04-24",
"subscriptionPhase": "terminated",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"paymentMethod": "CC",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://example.com/postback?" + urlencode(params)
response = urlopen(url)// GET https://example.com/postback
$params = [
"shopID" => "12345",
"type" => "subscription",
"subscriptionType" => "recurring",
"event" => "rebill",
"referenceID" => "order-1001",
"saleID" => "123456",
"transactionID" => "987654",
"amount" => "9.99",
"currency" => "USD",
"nextChargeOn" => "2015-04-24",
"subscriptionPhase" => "terminated",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"paymentMethod" => "CC",
"signature" => "abcdef0123456789abcdef0123456789abcdef01",
];// GET https://example.com/postback
Map<String, String> params = Map.ofEntries(
Map.entry("shopID", "12345"),
Map.entry("type", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "rebill"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("transactionID", "987654"),
Map.entry("amount", "9.99"),
Map.entry("currency", "USD"),
Map.entry("nextChargeOn", "2015-04-24"),
Map.entry("subscriptionPhase", "terminated"),
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
typestringsubscription
subscriptionTypestringrecurring
eventstringrebill
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
transactionIDnumberidentifier of the transaction in Verotel system
amountnumberamount to be processed in nnn.nn format
currencystring3 char ISO code of the Sale currency
nextChargeOnstringdate of next rebill [yyyy-mm-dd] eq. “2015-04-24”
subscriptionPhasestringnormal or discounted
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
Extend postback
Merchant or Verotel support may grant extra days to an active subscription. This means that the expiration date or the date of the next planned rebill gets shifted by number of days to the future. The extend postback is then sent to merchant’s postback URL to notify the merchant about that the subscription got extended.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=extend
&referenceID=order-1001
&saleID=123456
&nextChargeOn or expiresOn=value
&subscriptionPhase=terminated
&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("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "extend");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("nextChargeOn or expiresOn", "value");
url.searchParams.set("subscriptionPhase", "terminated");
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",
"type": "subscription",
"subscriptionType": "recurring",
"event": "extend",
"referenceID": "order-1001",
"saleID": "123456",
"nextChargeOn or expiresOn": "value",
"subscriptionPhase": "terminated",
"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",
"type" => "subscription",
"subscriptionType" => "recurring",
"event" => "extend",
"referenceID" => "order-1001",
"saleID" => "123456",
"nextChargeOn or expiresOn" => "value",
"subscriptionPhase" => "terminated",
"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("type", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "extend"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("nextChargeOn or expiresOn", "value"),
Map.entry("subscriptionPhase", "terminated"),
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
typestringsubscription
subscriptionTypestringrecurring or one-time
eventstringextend
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
nextChargeOn or expiresOnstringdate when cancelled or one-time subscription expires, or date of the next planned rebill [yyyy-mm-dd] e.g “2015-04-24”
subscriptionPhasestringtrial normal discounted
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Downgrade postback
If Merchant or Verotel support changes the next rebill price the Downgrade postback call is sent
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=downgrade
&referenceID=order-1001
&saleID=123456
&amount=9.99
¤cy=USD
&subscriptionPhase=normal
&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("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "downgrade");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("amount", "9.99");
url.searchParams.set("currency", "USD");
url.searchParams.set("subscriptionPhase", "normal");
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",
"type": "subscription",
"subscriptionType": "recurring",
"event": "downgrade",
"referenceID": "order-1001",
"saleID": "123456",
"amount": "9.99",
"currency": "USD",
"subscriptionPhase": "normal",
"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",
"type" => "subscription",
"subscriptionType" => "recurring",
"event" => "downgrade",
"referenceID" => "order-1001",
"saleID" => "123456",
"amount" => "9.99",
"currency" => "USD",
"subscriptionPhase" => "normal",
"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("type", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "downgrade"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("amount", "9.99"),
Map.entry("currency", "USD"),
Map.entry("subscriptionPhase", "normal"),
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
typestringsubscription
subscriptionTypestringrecurring or one-time
eventstringdowngrade
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
amountnumberamount to be processed in nnn.nn format
currencystring3 char ISO code of the Sale currency
subscriptionPhasestringnormal
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Cancel postback
Cancel postback call is sent to the merchant’s URL after the subscription is cancelled by the buyer, merchant, Verotel support or by the system.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=cancel
&referenceID=order-1001
&saleID=123456
&expiresOn=2015-04-24
&cancelledBy=merchant
&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("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "cancel");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("expiresOn", "2015-04-24");
url.searchParams.set("cancelledBy", "merchant");
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",
"type": "subscription",
"subscriptionType": "recurring",
"event": "cancel",
"referenceID": "order-1001",
"saleID": "123456",
"expiresOn": "2015-04-24",
"cancelledBy": "merchant",
"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",
"type" => "subscription",
"subscriptionType" => "recurring",
"event" => "cancel",
"referenceID" => "order-1001",
"saleID" => "123456",
"expiresOn" => "2015-04-24",
"cancelledBy" => "merchant",
"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("type", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "cancel"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("expiresOn", "2015-04-24"),
Map.entry("cancelledBy", "merchant"),
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
typestringsubscription
subscriptionTypestringrecurring
eventstringcancel
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
expiresOnstringexpiry date [yyyy-mm-dd] eq. “2015-04-24”
cancelledBystringuser support merchant system
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Uncancel postback
Occasionally, buyers wish to revert cancellation of their subscription. Uncancel can be done only by Verotel support. The postback call is sent to the merchant’s postback URL immediately after the subscription was uncancelled.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=uncancel
&referenceID=order-1001
&saleID=123456
&nextChargeOn=2015-04-24
&subscriptionPhase=terminated
&uncancelledBy=support
&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("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "uncancel");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("nextChargeOn", "2015-04-24");
url.searchParams.set("subscriptionPhase", "terminated");
url.searchParams.set("uncancelledBy", "support");
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",
"type": "subscription",
"subscriptionType": "recurring",
"event": "uncancel",
"referenceID": "order-1001",
"saleID": "123456",
"nextChargeOn": "2015-04-24",
"subscriptionPhase": "terminated",
"uncancelledBy": "support",
"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",
"type" => "subscription",
"subscriptionType" => "recurring",
"event" => "uncancel",
"referenceID" => "order-1001",
"saleID" => "123456",
"nextChargeOn" => "2015-04-24",
"subscriptionPhase" => "terminated",
"uncancelledBy" => "support",
"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("type", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "uncancel"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("nextChargeOn", "2015-04-24"),
Map.entry("subscriptionPhase", "terminated"),
Map.entry("uncancelledBy", "support"),
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
typestringsubscription
subscriptionTypestringrecurring
eventstringuncancel
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
nextChargeOnstringdate of the next planned rebill [yyyy-mm-dd] eq. “2015-04-24”
subscriptionPhasestringtrial normal discounted
uncancelledBystringsupport
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Expiry postback
Expiry postback call is sent to the merchant’s postback URL when the subscription gets terminated. The reason for the termination could be the end of a cancelled subscription, declined rebill transaction or termination by Verotel support or the merchant.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=expiry
&referenceID=order-1001
&saleID=123456
&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("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "expiry");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
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",
"type": "subscription",
"subscriptionType": "recurring",
"event": "expiry",
"referenceID": "order-1001",
"saleID": "123456",
"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",
"type" => "subscription",
"subscriptionType" => "recurring",
"event" => "expiry",
"referenceID" => "order-1001",
"saleID" => "123456",
"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("type", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "expiry"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
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
typestringsubscription
subscriptionTypestringrecurring or one-time
eventstringexpiry
referenceIDstringmerchant reference identifier. It must be unique if provided
saleIDnumberidentifier of the sale in the Verotel system
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Credit postback
Credit postback call is sent to the merchant’s postback URL when any transaction of the subscription is credited by merchant, Verotel support or by system (e.g. when an automated refund is performed). The refund also terminates subscription.
GET https://example.com/postback
?shopID=12345
&event=credit
&referenceID=order-1001
&saleID=123456
&priceAmount=9.99
&priceCurrency=USD
&transactionID=987654
&parentID=456789
&subscriptionType=recurring
&subscriptionPhase=terminated
&type=subscription
&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("subscriptionType", "recurring");
url.searchParams.set("subscriptionPhase", "terminated");
url.searchParams.set("type", "subscription");
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",
"subscriptionType": "recurring",
"subscriptionPhase": "terminated",
"type": "subscription",
"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",
"subscriptionType" => "recurring",
"subscriptionPhase" => "terminated",
"type" => "subscription",
"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("subscriptionType", "recurring"),
Map.entry("subscriptionPhase", "terminated"),
Map.entry("type", "subscription"),
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
subscriptionTypestringrecurring or one-time
subscriptionPhasestringterminated or normal (for partial credit without terminate initiated)
typestringsubscription
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
&subscriptionType=recurring
&subscriptionPhase=terminated
&type=subscription
&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("subscriptionType", "recurring");
url.searchParams.set("subscriptionPhase", "terminated");
url.searchParams.set("type", "subscription");
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",
"subscriptionType": "recurring",
"subscriptionPhase": "terminated",
"type": "subscription",
"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",
"subscriptionType" => "recurring",
"subscriptionPhase" => "terminated",
"type" => "subscription",
"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("subscriptionType", "recurring"),
Map.entry("subscriptionPhase", "terminated"),
Map.entry("type", "subscription"),
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
subscriptionTypestringrecurring or one-time
subscriptionPhasestringterminated
typestringsubscription
custom1stringpass-through variable - max 255 printable characters
custom2stringpass-through variable - max 255 printable characters
custom3stringpass-through variable - max 255 printable characters
signaturestringSignature calculation
Upgrade postback
Upgrade postback call is sent to the merchant’s postback URL when the subscription is switched from one plan to another. The postback is sent instead of the Successful sale postbacks when the new subscription the buyer is switching to is successfully created and the previous subscription is terminated in Verotel system (No Expiry postback is sent). See “FlexPay API Upgrade” document for more details.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=upgrade
&referenceID=order-1001
&saleID=123456
&transactionID=987654
&precededBySaleID=123450
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&expiresOn or nextChargeOn=value
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&paymentMethod=CC
&signature=abcdef0123456789abcdef0123456789abcdef01
&truncatedPAN=411111******1111
&CCBrand=VISAconst url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "upgrade");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("transactionID", "987654");
url.searchParams.set("precededBySaleID", "123450");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("period", "P30D");
url.searchParams.set("expiresOn or nextChargeOn", "value");
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");
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": "subscription",
"subscriptionType": "recurring",
"event": "upgrade",
"referenceID": "order-1001",
"saleID": "123456",
"transactionID": "987654",
"precededBySaleID": "123450",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"expiresOn or nextChargeOn": "value",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"paymentMethod": "CC",
"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" => "subscription",
"subscriptionType" => "recurring",
"event" => "upgrade",
"referenceID" => "order-1001",
"saleID" => "123456",
"transactionID" => "987654",
"precededBySaleID" => "123450",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"period" => "P30D",
"expiresOn or nextChargeOn" => "value",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"paymentMethod" => "CC",
"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", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "upgrade"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("transactionID", "987654"),
Map.entry("precededBySaleID", "123450"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("period", "P30D"),
Map.entry("expiresOn or nextChargeOn", "value"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("paymentMethod", "CC"),
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
typestringsubscription
subscriptionTypestringone-time or recurring
eventstringupgrade
referenceIDstringmerchant reference identifier if provided in the first sale.
saleIDnumberidentifier of the sale in the Verotel system
transactionIDnumberidentifier of the transaction in the Verotel system (only avaible for postbacks version 2)
precededBySaleIDnumberIdentifier of the previous sale the enduser is switching from
priceAmountnumberamount to be processed in nnn.nn format
priceCurrencystring3 char ISO code of the Sale currency
periodstringsubscription duration in ISO8601 format
expiresOn or nextChargeOnstringdate of next rebill or expiry date [yyyy-mm-dd] eq. “2015-04-24”
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
truncatedPANstringTruncated (masked) payment instrument identification, e.g. card number
CCBrandstringOnly present if paid via Credit Card, represents the card brand, e.g. VISA
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(123456);
// fetch URL content
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 format
priceCurrencystring3 char ISO code of the Sale currency
trialAmountstringtrial period processed amount
trialPeriodstringduration of trial period in ISO8601 format
discountAmountstringreccurring amount after cancel discount confirmation by buyer
periodstringduration in ISO8601 format, for example: P30D
descriptionstringProduct description text - max 100 printable characters
typestringpurchase or subscription
subscriptionTypestringone-time or recurring
expiredstringyes or no
expiresOnstringwhen subscription will be terminated
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
cancelledstringyes or no
cancelledOnstringTimestamp of cancellation
cancelledBystringuser support merchant system
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)
Cancel subscription request
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
To allow your subscribers to cancel their subscriptions on your website you can now generate a subscription specific cancel URL.
HTTP request
Verotel
GET https://secure.verotel.com/cancel-subscription?
CardBilling
GET https://secure.billing.creditcard/cancel-subscription?
GayCharge
GET https://secure.gaycharge.com/cancel-subscription?
YoursafeDirect
GET https://secure.yoursafedirect.com/cancel-subscription?
$brand = Verotel\FlexPay\Brand::create_from_merchant_id(/* Your customer ID */ '9804000000000000');
$flexpayClient = new Verotel\FlexPay\Client(/* shop ID */ 12345, "FlexPay Signature Key", $brand);
$cancelSubscriptionURL = $flexpayClient->get_cancel_subscription_URL([
"saleID" => 654321
]);
URL cancelUrl = flexPayClient.getCancelSubscriptionUrl(1234);
GET https://secure.verotel.com/cancel-subscription
?version=4
&shopID=12345
&saleID=123456
&signature=abcdef0123456789abcdef0123456789abcdef01const url = new URL("https://secure.verotel.com/cancel-subscription");
url.searchParams.set("version", "4");
url.searchParams.set("shopID", "12345");
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",
"saleID": "123456",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
}
url = "https://secure.verotel.com/cancel-subscription?" + urlencode(params)
response = urlopen(url)/cancel-subscriptionQuery parameters
versionstringrequiredversion version of the FlexPay call, 4 for this version
shopIDnumberrequirednumerical ID of the website or shop in Verotel system
saleIDnumberrequiredVerotel saleID identifier
signaturestringrequiredSignature calculation
Upgrade subscription request
Examples are for Verotel FlexPay PHP client library
Examples are for FlexPay Java client library
Subscription upgrade allows switching from one currently active subscription to a new one with new pricing and rebill period. It is possible to switch between recurring and one-time subscriptions, between payment methods and change the periods and amounts.
If successful – an upgrade postback is sent, the current subscription is terminated in Verotel system
(the expiry postback is not send in this case) and the buyer continues with the new subscription.
Upgrade Options
The optional upgradeOption parameter specifies how the remaining time from the previous sale
is handled:
extend- Any remaining time from previous sale is added to the initial period of the new subscription. This is also how the remaining time is handled if the “upgradeOption” parameter is not specified.lost- Any remaining time from previous sale is ignored/lost.
Constructing the Upgrade request
The “upgrade” request is used to redirect buyer to the Verotel Order Page in order to process superseding subscription with a given amount, duration and currency.
The upgrade request is like the startorder request but the type needs to be “upgradesubscription” and there is mandatory precedingSaleID parameter.
Please note that referenceID parameter is not accepted in the upgrade request. If referenceID was supplied initially in the startorder of the preceding subscription, it is copied over to the new upgraded subscription.
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 and YOURSAFE_DIRECT only support one-time |
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 |
NOTE: email is excluded from signature calculations (max 100 chars else 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);
$upgradeSubscriptionURL = $flexpayClient->get_upgrade_subscription_URL([
"period" => 'P30D',
"name" => 'Upgrade to one year subscription'
"precedingSaleID" => 123456,
"priceAmount" => 20,
"priceCurrency" => 'USD',
"period" => 'P1Y',
"upgradeOption" => 'extend',
]);
URL upgradeSubscriptionURL = flexpayClient.getUpgradeSubscriptionUrl(
1234 // preceding sale ID
"P12D", // period
SubscriptionType.recurring,
BigDecimal.valueOf(24), // price amount
SaleCurrency.EUR, // price currency
);
GET https://secure.verotel.com/startorder
?version=4
&shopID=12345
&type=upgradesubscription
&precedingSaleID=123450
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&subscriptionType=recurring
&name=Test subscription
&upgradeOption=lost
&paymentMethod=CC
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&successURL=https://example.com/success
&email=buyer@example.com
&signature=abcdef0123456789abcdef0123456789abcdef01
&trialAmount=5.00
&trialPeriod=P7Dconst url = new URL("https://secure.verotel.com/startorder");
url.searchParams.set("version", "4");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "upgradesubscription");
url.searchParams.set("precedingSaleID", "123450");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("period", "P30D");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("name", "Test subscription");
url.searchParams.set("upgradeOption", "lost");
url.searchParams.set("paymentMethod", "CC");
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("email", "buyer@example.com");
url.searchParams.set("signature", "abcdef0123456789abcdef0123456789abcdef01");
url.searchParams.set("trialAmount", "5.00");
url.searchParams.set("trialPeriod", "P7D");
const response = await fetch(url);from urllib.parse import urlencode
from urllib.request import urlopen
params = {
"version": "4",
"shopID": "12345",
"type": "upgradesubscription",
"precedingSaleID": "123450",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"subscriptionType": "recurring",
"name": "Test subscription",
"upgradeOption": "lost",
"paymentMethod": "CC",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"successURL": "https://example.com/success",
"email": "buyer@example.com",
"signature": "abcdef0123456789abcdef0123456789abcdef01",
"trialAmount": "5.00",
"trialPeriod": "P7D",
}
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
typestringrequiredupgradesubscription
precedingSaleIDnumberrequiredIdentificator of sale the buyer is upgrading from
priceAmountnumberrequiredamount 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
periodstringrequiredduration in ISO8601 format, for example: P30D, minimum is 7 days for recurring and 2 days for on-time
subscriptionTypestringrequiredone-timeorrecurring- NOTE:
DDEUandYOURSAFE_DIRECTonly supportone-time
namestringdescription of the product. Text is displayed on the order page - max 100 printable characters
upgradeOptionstringlost or extend - – this option defines how to deal with the remaining period from the previous sale, if not provided the remaining period is added to new sale (“same as “extend”)
paymentMethodstring- payment method,
CC,YOURSAFE_DIRECT,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
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.
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 will be ignored)
signaturestringrequiredSignature calculation
trialAmountnumberamount to be processed (max 2 decimal places, stripped zeroes) for the initial trial period
trialPeriodstringduration in ISO8601 format
GET https://example.com/success
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=initial
&referenceID=order-1001
&saleID=123456
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&trialAmount=5.00
&trialPeriod=P7D
&expiresOn or nextChargeOn=value
&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", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "initial");
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("period", "P30D");
url.searchParams.set("trialAmount", "5.00");
url.searchParams.set("trialPeriod", "P7D");
url.searchParams.set("expiresOn or nextChargeOn", "value");
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": "subscription",
"subscriptionType": "recurring",
"event": "initial",
"referenceID": "order-1001",
"saleID": "123456",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"trialAmount": "5.00",
"trialPeriod": "P7D",
"expiresOn or nextChargeOn": "value",
"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" => "subscription",
"subscriptionType" => "recurring",
"event" => "initial",
"referenceID" => "order-1001",
"saleID" => "123456",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"period" => "P30D",
"trialAmount" => "5.00",
"trialPeriod" => "P7D",
"expiresOn or nextChargeOn" => "value",
"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", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "initial"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("period", "P30D"),
Map.entry("trialAmount", "5.00"),
Map.entry("trialPeriod", "P7D"),
Map.entry("expiresOn or nextChargeOn", "value"),
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
typestringsubscription
subscriptionTypestringone-time or recurring
eventstringinitial
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
periodstringsubscription duration in ISO8601 format
trialAmountnumberamount to be processed (max 2 decimal places, stripped zeroes) for the initial trial period
trialPeriodstringduration in ISO8601 format
expiresOn or nextChargeOnstringdate of next rebill or expiry date [yyyy-mm-dd] eq. “2015-04-24”
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
Upgrade postback
Upgrade postback call is sent to the merchant’s postback URL when the subscription is switched from one plan to another. The postback is sent instead of the Successful sale postbacks when the new subscription the buyer is switching to is successfully created and the previous subscription is terminated in Verotel system (No Expiry postback is sent). See “FlexPay API Upgrade” document for more details.
GET https://example.com/postback
?shopID=12345
&type=subscription
&subscriptionType=recurring
&event=upgrade
&referenceID=order-1001
&saleID=123456
&transactionID=987654
&precededBySaleID=123450
&priceAmount=9.99
&priceCurrency=USD
&period=P30D
&expiresOn or nextChargeOn=value
&custom1=xxyyzz
&custom2=custom-2
&custom3=custom-3
&paymentMethod=CC
&signature=abcdef0123456789abcdef0123456789abcdef01
&truncatedPAN=411111******1111
&CCBrand=VISAconst url = new URL("https://example.com/postback");
url.searchParams.set("shopID", "12345");
url.searchParams.set("type", "subscription");
url.searchParams.set("subscriptionType", "recurring");
url.searchParams.set("event", "upgrade");
url.searchParams.set("referenceID", "order-1001");
url.searchParams.set("saleID", "123456");
url.searchParams.set("transactionID", "987654");
url.searchParams.set("precededBySaleID", "123450");
url.searchParams.set("priceAmount", "9.99");
url.searchParams.set("priceCurrency", "USD");
url.searchParams.set("period", "P30D");
url.searchParams.set("expiresOn or nextChargeOn", "value");
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");
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": "subscription",
"subscriptionType": "recurring",
"event": "upgrade",
"referenceID": "order-1001",
"saleID": "123456",
"transactionID": "987654",
"precededBySaleID": "123450",
"priceAmount": "9.99",
"priceCurrency": "USD",
"period": "P30D",
"expiresOn or nextChargeOn": "value",
"custom1": "xxyyzz",
"custom2": "custom-2",
"custom3": "custom-3",
"paymentMethod": "CC",
"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" => "subscription",
"subscriptionType" => "recurring",
"event" => "upgrade",
"referenceID" => "order-1001",
"saleID" => "123456",
"transactionID" => "987654",
"precededBySaleID" => "123450",
"priceAmount" => "9.99",
"priceCurrency" => "USD",
"period" => "P30D",
"expiresOn or nextChargeOn" => "value",
"custom1" => "xxyyzz",
"custom2" => "custom-2",
"custom3" => "custom-3",
"paymentMethod" => "CC",
"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", "subscription"),
Map.entry("subscriptionType", "recurring"),
Map.entry("event", "upgrade"),
Map.entry("referenceID", "order-1001"),
Map.entry("saleID", "123456"),
Map.entry("transactionID", "987654"),
Map.entry("precededBySaleID", "123450"),
Map.entry("priceAmount", "9.99"),
Map.entry("priceCurrency", "USD"),
Map.entry("period", "P30D"),
Map.entry("expiresOn or nextChargeOn", "value"),
Map.entry("custom1", "xxyyzz"),
Map.entry("custom2", "custom-2"),
Map.entry("custom3", "custom-3"),
Map.entry("paymentMethod", "CC"),
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
typestringsubscription
subscriptionTypestringone-time or recurring
eventstringupgrade
referenceIDstringmerchant reference identifier if provided in the first sale.
saleIDnumberidentifier of the sale in the Verotel system
transactionIDnumberidentifier of the transaction in the Verotel system (only avaible for postbacks version 2)
precededBySaleIDnumberIdentifier of the previous sale the enduser is switching from
priceAmountnumberamount to be processed in nnn.nn format
priceCurrencystring3 char ISO code of the Sale currency
periodstringsubscription duration in ISO8601 format
expiresOn or nextChargeOnstringdate of next rebill or expiry date [yyyy-mm-dd] eq. “2015-04-24”
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
truncatedPANstringTruncated (masked) payment instrument identification, e.g. card number
CCBrandstringOnly present if paid via Credit Card, represents the card brand, e.g. VISA
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/ |