Create a Payment
Endpoints
HTTP Method | API URL | API Version |
---|---|---|
POST | https://connect2.payxpert.com/transaction/prepare | >= 002 |
POST | https://connect2.payxpert.com/payment/prepare | >= 002.50 |
This call corresponds to the step 2 of the global workflow. It is used to initialize a payment with all the required data (excepting payment mean information).
The information for the payment are serialized in JSON format and are transmitted in the body of the request.
Accepted parameters
Name | Type | Description | Required | |
---|---|---|---|---|
General Fields | ||||
apiVersion | String(8) | API version to be used (002.70) | yes | |
Order information Fields | ||||
shopper | Shopper Object | Information about shopper | yes | |
order | Order Object | Information about order | yes | |
shipping | Shipping Object | Information about shipping | no | |
currency | String(3) | Currency for the current order | yes | |
amount | Integer(32bits) | The payment amount in cents (for 1€ => 100) | yes | |
Payment Detail Fields | ||||
paymentMethod | String(32) | The preferred payment method to use to complete the payment. See the possible values. This will change the type of the payment page displayed. If no value is specified and the account has several payment methods available, a selection page will be displayed to the customer. |
yes for Seamless Checkout | |
paymentNetwork | String(32) | The network in case the payment method has several. See the possible values. | no | |
operation | String(32) | Can be Authorize or Sale (default value is according to what is configured for the account). May be ignored according to the payment type | No | |
paymentMode | String(30) | Can be either : Single, OnShipping, Recurrent, InstalmentsPayments | yes | |
secure3d | Boolean | “true” or “false” (default false). In the case of CreditCard payment method, instruct to enable 3D Secure on the transaction. The merchant account must support this. | No | |
Predefined Subscription Fields | ||||
offerID | Integer(64bits) | Predefined price point with initial and rebill period | no | |
On the fly Subscription Fields (only to be used by special agreement) | ||||
subscriptionType | String(32) | can be normal, partpayment, infinite, onetime or lifetime. See Subscription Types (only to be used by special agreement). | no | |
trialPeriod | String(10) | Duration of the initial period in ISO 8601 duration format (only to be used by special agreement). | no | |
rebillAmount | Integer(32bits) | Number in minor unit, amount to be rebilled after the initial period (only to be used by special agreement). | no | |
rebillPeriod | String(10) | Duration between re-billing transactions in ISO 8601 duration format (only to be used by special agreement). | no | |
rebillMaxIteration | Integer(32bits) | Number of re-billing transactions that will be settled (only to be used by special agreement). | no | |
Template and Control Fields | ||||
ctrlRedirectURL | String(2048) | The URL where to redirect the customer after the payment processing | no (yes for API version <= 002) | |
ctrlCallbackURL | String(2048) | A URL that will be notified of the status of the payment | yes for Seamless Checkout | |
ctrlCustomData | String(2048) | Custom data that will be returned back with the status of the payment | no | |
timeOut | String(10) | Validity period for the payment link in ISO 8601 duration format. Maximum accepted value is 3 months, default value is 1 minute (when user is immediately redirected towards the payment page). It is advised to keep this value as low as possible to avoid problem. Should be used only when sending the payment link using an asynchronous mechanism (email, MMS…). | no | |
merchantNotification | Boolean | “true” or “false” (default false). Whether to send notification to the merchant after the payment. | no | |
merchantNotificationTo | String(100) | Merchant email address to send payment notification | no (yes if merchantNotification is true) | |
merchantNotificationLang | String(2) | Lang to use to send the merchant email notification (en, fr, es or it). Defaults to the lang of the customer. | no | |
themeID | Integer(64bits) | Select a predefined payment page template | no |
Name | Type | Description | Required | API Version |
---|---|---|---|---|
Authentication Fields | ||||
afClientId | Integer(32bits) | Client ID for the antifraud system (unused) | no | >= 002 & <= 002.01 |
afPassword | String(64) | Password for the antifraud system (unused) | no | >= 002 & <= 002.01 |
apiVersion | String(8) | API version to be used (default 002) | yes | >= 002 |
Customer Fields | ||||
shopperID | String(32) | Merchant unique customer numeric identifier | no | >= 002, >=002.50 change from Integer(32bits) to String(32) |
shopperEmail | String(100) | Customer email address | no | >= 002 |
shipToFirstName | String(35) | Customer first name for shipping | no | >= 002 |
shipToLastName | String(35) | Customer last name for shipping | no | >= 002 |
shipToCompany | String(128) | Customer company name for shipping | no | >= 002 |
shipToPhone | String(20) | Customer phone for shipping ; if many, separate by “;” | no | >= 002 |
shipToAddress | String(255) | Customer address for shipping | no | >= 002 |
shipToState | String(30) | Customer state for shipping | no | >= 002 |
shipToZipcode | String(10) | Customer ZIP Code for shipping | no | >= 002 |
shipToCity | String(50) | Customer city for shipping | no | >= 002 |
shipToCountryCode | String(2) | Customer country for shipping | no | >= 002 |
shopperFirstName | String(35) | Customer first name for invoicing | no | >= 002 |
shopperLastName | String(35) | Customer last name for invoicing | no | >= 002 |
shopperPhone | String(20) | Customer phone for invoicing ; if many, separate by “;” | no | >= 002 |
shopperAddress | String(255) | Customer address for invoicing | no | >= 002 |
shopperState | String(30) | Customer state for invoicing | no | >= 002 |
shopperZipcode | String(10) | Customer ZIP Code for invoicing | no | >= 002 |
shopperCity | String(50) | Customer city for invoicing | no | >= 002 |
shopperCountryCode | String(2) | Customer country for invoicing | no | >= 002 |
shopperCompany | String(128) | Customer company name for invoicing | no | >= 002 |
shopperLoyaltyProgram | String(50) | Customer Loyalty Program name | no | >= 002 |
shopperBirthDate | String(8) | Date of shopper birth date, format YYYYMMDD | maybe | >= 002.03 |
shopperIDNumber | String(32) | Customers document (passport number, ID number, taxpayer ID…) | maybe | >= 002.03 |
Order Fields | ||||
orderID | String(100) | Merchant internal unique order identifier | yes | >= 002 |
currency | String(3) | Currency for the current order | yes | >= 002 |
amount | Integer(32bits) | The payment amount in cents (for 1€ => 100) | yes | >= 002 |
orderTotalWithoutShipping | Integer(32bits) | The payment amount in cents, without shipping fee | no | >= 002 |
orderShippingPrice | Integer(32bits) | The shipping amount in cents (for 1€ => 100) | no | >= 002 |
orderDiscount | Integer(32bits) | The discount amount in cents (for 1€ => 100) | no | >= 002 |
customerIP | String(15) | The IP address of the customer | yes (field not present with API >= 002.01) | < 002.01 |
orderFOLanguage | String(50) | Language of the Front Office used to validate the order | no | >= 002 |
orderDescription | String(500) | Short description of the product purchased by the customer | no | >= 002 |
orderCartContent | Array of objects | Product or service bought - see details here | no | >= 002 |
Shipping Fields | ||||
shippingType | String(50) | Can be either : Physical (for physical goods), Virtual (for dematerialized goods), Access (for protected content) | yes | >= 002 |
shippingName | String(50) | In case of Physical shipping type, name of the shipping company | no | >= 002 |
Payment Detail Fields | ||||
paymentType | String(32) | See paymentMethod. For API >= 002.50, if no value is specified and the account has several payment types available, a selection page will be displayed to the customer. | < 002.50: yes >=002.50: no |
>= 002 < 002.60 |
paymentMethod | String(32) | The preferred payment method to use to complete the payment. See the possible values. This will change the type of the payment page displayed. If no value is specified and the account has several payment methods available, a selection page will be displayed to the customer. |
yes for Seamless Checkout | >= 002.60 |
paymentNetwork | String(32) | The network in case the payment method has several. See the possible values. | no | >= 002.60 |
provider | String(64) | See paymentNetwork | no | >= 002.50 < 002.60 |
operation | String(32) | Can be Authorize or Sale (default value is according to what is configured for the account). May be ignored according to the payment type | No | >= 002.03 |
paymentMode | String(30) | Can be either : Single, OnShipping, Recurrent, InstalmentsPayments | yes | >= 002 |
secure3d | Boolean | “true” or “false” (default false). In the case of CreditCard payment type, instruct to enable Secure 3D on the transaction. The merchant account must support this. | No | >= 002 |
Predefined Subscription Fields | ||||
offerID | Integer(64bits) | Predefined price point with initial and rebill period | no | >= 002 |
On the fly Subscription Fields (only to be used by special agreement) | ||||
subscriptionType | String(32) | can be normal, partpayment, infinite, onetime or lifetime. See Subscription Types (only to be used by special agreement). | no | >= 002 |
trialPeriod | String(10) | Duration of the initial period in ISO 8601 duration format (only to be used by special agreement). | no | >= 002 |
rebillAmount | Integer(32bits) | Number in minor unit, amount to be rebilled after the initial period (only to be used by special agreement). | no | >= 002 |
rebillPeriod | String(10) | Duration between re-billing transactions in ISO 8601 duration format (only to be used by special agreement). | no | >= 002 |
rebillMaxIteration | Integer(32bits) | Number of re-billing transactions that will be settled (only to be used by special agreement). | no | >= 002 |
Template and Control Fields | ||||
ctrlRedirectURL | String(2048) | The URL where to redirect the customer after the payment processing | no (yes for API version <= 002) | >= 002 |
ctrlCallbackURL | String(2048) | A URL that will be notified of the status of the payment | yes for Seamless Checkout | >= 002 |
ctrlCustomData | String(2048) | Custom data that will be returned back with the status of the payment | no | >= 002 |
timeOut | String(10) | Validity period for the payment link in ISO 8601 duration format. Maximum accepted value is 3 months, default value is 1 minute (when user is immediately redirected towards the payment page). It is advised to keep this value as low as possible to avoid problem. Should be used only when sending the payment link using an asynchronous mechanism (email, MMS…). | no | >= 002.01 |
merchantNotification | Boolean | “true” or “false” (default false). Whether to send notification to the merchant after the payment. | no | >= 002.01 |
merchantNotificationTo | String(100) | Merchant email address to send payment notification | no (yes if merchantNotification is true) | >= 002.01 |
merchantNotificationLang | String(2) | Lang to use to send the merchant email notification (en, fr, es or it). Defaults to the lang of the customer. | no | >= 002.01 |
themeID | Integer(64bits) | Select a predefined payment page template | no | >= 002 |
- Notes:
- 3DSecure V2 is available at version 002.70
- While testing your 3DSv2 implementation, you can set the parameter
shopper.account.suspicious
astrue
to trigger a challenge.false
should result in frictionless flow. - In the case of a non subscription creation payment,
paymentMode
may only take Single or OnShipping as a value. - In the case of a subscription creation payment:
- If the merchant is allowed to do on the fly subscription, subscription details can be specified in the On the fly Subscription fields (don’t use
offerID
in this case) - If the merchant is not allowed to do on the fly subscription or wants to use a predefined offer, the
offerID
field allows to choose the subscription to initiate paymentMode
may only take Recurrent or InstalmentsPayments
- If the merchant is allowed to do on the fly subscription, subscription details can be specified in the On the fly Subscription fields (don’t use
Payment Methods and Networks
Some payment methods can have several networks. Adding the payment network parameter in the API call will make the application create a payment with the chosen payment network. Not providing the network field for multi-networks payment methods will generate an error.
Payment Method | Payment Network | Description |
---|---|---|
CreditCard | Credit Card (brands availability according to your contract) | |
WeChat Pay | ||
Alipay | Alipay | |
DirectDebit | SEPA Direct Debit | |
Bancontact | Bancontact | |
BankTransfer | sofort | Bank transfer using Klarna (Sofort) |
BankTransfer | przelewy24 | Bank transfer using Przelewy24 (Poland only) |
BankTransfer | ideal | Bank transfer using iDeal |
BankTransfer | giropay | Bank transfer using Giropay |
BankTransfer | eps | Bank transfer using EPS |
BankTransfer | poli | Bank transfer using POLi |
BankTransfer | dragonpay | Bank transfer using DragonPay |
BankTransfer | trustly | Bank transfer using Trustly |
Line | Line Pay |
Response
The body of the response to a transaction creation request is in JSON format.
The following fields are present in the response :
Name | Type | Description | API Version |
---|---|---|---|
code | String(3) | API response code (see response codes for possible values) | >= 002 |
message | String(128) | Human readable message associated with the code | >= 002 |
customerToken | String | The customer token to be used for payment processing (only present if payment creation was successful) | >= 002 |
merchantToken | String(32) | The merchant token to be used for payment status request (only present if payment creation was successful) | >= 002 |
Response codes
Here are the possible response code to a payment creation:
Response code | Response Message |
---|---|
200 | Request processed successfully |
400 | Missing parameter |
401 | Missing parameter in request |
402 | Error during JSON deserialization of parameter |
500 | Error handling the request |
501 | Incorrect data in submitted request |
{
"code": "200",
"message": "Request processed successfully",
"customerToken": "1234",
"merchantToken": "1234"
}
Code samples
use PayXpert\Connect2Pay\Connect2PayClient;
use PayXpert\Connect2Pay\containers\request\PaymentPrepareRequest;
use PayXpert\Connect2Pay\containers\Order;
use PayXpert\Connect2Pay\containers\Shipping;
use PayXpert\Connect2Pay\containers\Shopper;
use PayXpert\Connect2Pay\containers\Account;
use PayXpert\Connect2Pay\containers\constant\OrderShippingType;
use PayXpert\Connect2Pay\containers\constant\OrderType;
use PayXpert\Connect2Pay\containers\constant\PaymentMethod;
use PayXpert\Connect2Pay\containers\constant\PaymentMode;
use PayXpert\Connect2Pay\containers\constant\AccountAge;
use PayXpert\Connect2Pay\containers\constant\AccountLastChange;
use PayXpert\Connect2Pay\containers\constant\AccountPaymentMeanAge;
$connect2pay = "https://connect2.payxpert.com";
// This will be provided once your account is approved
$originator = "000000";
$password = "Gr3atPassw0rd!";
$c2pClient = new Connect2PayClient($connect2pay, $originator, $password);
$prepareRequest = new PaymentPrepareRequest();
$shopper = new Shopper();
$account = new Account();
$order = new Order();
$shipping = new Shipping();
// Set all information for the payment
$prepareRequest->setPaymentMethod(PaymentMethod::CREDIT_CARD);
$prepareRequest->setPaymentMode(PaymentMode::SINGLE);
// To charge €25.99
$prepareRequest->setCurrency("EUR");
$prepareRequest->setAmount(2599);
// Extra custom data that are returned with the payment status
$prepareRequest->setCtrlCustomData("Give that back to me please!!");
// Where the customer will be redirected after the payment
$prepareRequest->setCtrlRedirectURL("https://merchant.example.com/payment/redirect");
// URL on the merchant site that will receive the callback notification
$prepareRequest->setCtrlCallbackURL("https://merchant.example.com/payment/callback");
$order->setId("ABC-123456");
$order->setShippingType(OrderShippingType::DIGITAL_GOODS);
$order->setType(OrderType::GOODS_SERVICE);
$order->setDescription("Payment of €25.99");
$shopper->setId("1234567WX");
$shopper->setFirstName("John")->setLastName("Doe");
$shopper->setAddress1("Debit Street, 45");
$shopper->setZipcode("3456TRG")->setCity("New York")->setState("NY")->setCountryCode("US");
$shopper->setHomePhonePrefix("212")->setHomePhone("12345678");
$shopper->setEmail("shopper@example.com");
$account->setAge(AccountAge::LESS_30_DAYS);
$account->setDate("20210106");
$account->setLastChange(AccountLastChange::LESS_30_DAYS);
$account->setLastChangeDate("20210106");
$account->setPaymentMeanAge(AccountPaymentMeanAge::LESS_30_DAYS);
$account->setPaymentMeanDate("20210106");
// Set 'true' to trigger SCA challenge
$account->setSuspicious(false);
$shipping->setName("Lady Gogo");
$shipping->setAddress1("125 Main Street");
$shipping->setZipcode("ABC-5678")->setState("NY")->setCity("New York")->setCountryCode("US");
$shipping->setPhone("+47123456789");
$shopper->setAccount($account);
$prepareRequest->setShopper($shopper);
$prepareRequest->setOrder($order);
$prepareRequest->setShipping($shipping);
$result = $c2pClient->preparePayment($prepareRequest);
if ($result !== false) {
// The customer token info returned by the payment page could be saved in session (may
// be used later when the customer will be redirected from the payment page)
$_SESSION['merchantToken'] = $result->getMerchantToken();
// The merchantToken must also be used later to validate the callback to avoid that anyone
// could call it and abusively validate the payment. It may be stored in local database for this.
// Now redirect the customer to the payment page
header('Location: ' . $c2pClient->getCustomerRedirectURL($result));
} else {
echo "Payment preparation error occurred: " . $c2pClient->getClientErrorMessage() . "\n";
}
use PayXpert\Connect2Pay\Connect2PayClient;
$url = "https://connect2.payxpert.com";
// This will be provided once your account is approved
$originator = "000000";
$password = "Gr3atPassw0rd!";
$c2pClient = new Connect2PayClient($url, $originator, $password);
// Set all information for the payment
$c2pClient->setOrderID("ABC-123456");
$c2pClient->setPaymentMethod(Connect2PayClient::PAYMENT_METHOD_CREDITCARD); // or PAYMENT_METHOD_DIRECTDEBIT for SEPA, for example
$c2pClient->setPaymentMode(Connect2PayClient::PAYMENT_MODE_SINGLE);
$c2pClient->setShopperID("1234567WX");
$c2pClient->setShippingType(Connect2PayClient::SHIPPING_TYPE_VIRTUAL);
// To charge €25.99
$c2pClient->setCurrency("EUR");
$c2pClient->setAmount(2599);
$c2pClient->setOrderDescription("Payment of €25.99");
$c2pClient->setShopperFirstName("John");
$c2pClient->setShopperLastName("Doe");
$c2pClient->setShopperAddress("NA");
$c2pClient->setShopperZipcode("NA");
$c2pClient->setShopperCity("NA");
$c2pClient->setShopperCountryCode("GB");
$c2pClient->setShopperPhone("+4712345678");
$c2pClient->setShopperEmail("shopper@example.com");
// Extra custom data that are returned with the payment status
$c2pClient->setCtrlCustomData("Give that back to me please !!");
// Where the customer will be redirected after the payment
$c2pClient->setCtrlRedirectURL("https://merchant.example.com/payment/redirect");
// URL on the merchant site that will receive the callback notification
$c2pClient->setCtrlCallbackURL("https://merchant.example.com/payment/callback");
if ($c2pClient->validate()) {
if ($c2pClient->preparePayment()) {
// The customer token info returned by the payment page could be saved in session (may
// be used later when the customer will be redirected from the payment page)
$_SESSION['merchantToken'] = $c2pClient->getMerchantToken();
// The merchantToken must also be used later to validate the callback to avoid that anyone
// could call it and abusively validate the payment. It may be stored in local database for this.
// Now redirect the customer to the payment page
header('Location: ' . $c2pClient->getCustomerRedirectURL());
} else {
echo "error prepareTransaction: ";
echo $c2pClient->getClientErrorMessage() . "\n";
}
} else {
echo "Validation error occurred: " . $c2pClient->getClientErrorMessage() . "\n";
}
import com.payxpert.connect2pay.client.containers.Account;
import com.payxpert.connect2pay.client.containers.Order;
import com.payxpert.connect2pay.client.containers.Shipping;
import com.payxpert.connect2pay.client.containers.Shopper;
import com.payxpert.connect2pay.client.requests.PaymentRequest;
import com.payxpert.connect2pay.constants.PaymentMode;
import com.payxpert.connect2pay.constants.sca.ShippingType;
import com.payxpert.connect2pay.constants.sca.ShopperAccountAge;
import com.payxpert.connect2pay.constants.sca.ShopperAccountLastChange;
class TestPayment {
public void processPayment() {
// Process a payment of €39.99
PaymentRequest request = new PaymentRequest();
request.setCurrency("EUR").setAmount(3999);
request.setPaymentMode(PaymentMode.SINGLE);
// User will be redirected here when clicking on "Go back to merchant" button
request.setCtrlRedirectURL("http://my.website/somewhere");
// The payment page will do a callback on this URL after the payment is processed
request.setCtrlCallbackURL("http://my.website/payment-callback");
Order order = new Order();
order.setId("1234ABCD").setShippingType(ShippingType.DIGITAL_GOODS);
Shopper shopper = new Shopper();
shopper.setEmail("test@example.com").setFirstName("John").setLastName("Doe")
.setHomePhonePrefix("47").setHomePhone("123456789").setAddress1("Main Street 41")
.setZipcode("123456").setCity("London").setCountryCode("GB");
Account account = new Account();
account.setAge(ShopperAccountAge.BETWEEN_30_60_DAYS).setSuspicious(false)
.setLastChange(ShopperAccountLastChange.BETWEEN_30_60_DAYS);
shopper.setAccount(account);
Shipping shipping = new Shipping();
shipping.setName("Jane Doe").setAddress1("Other Street, 54").setCity("London")
.setZipcode("654321").setCountryCode("GB");
request.setOrder(order);
request.setShopper(shopper);
request.setShipping(shipping);
// Validate the request
try {
request.validate();
} catch (BadRequestException e) {
logger.error("Ooops, an error occurred validating the payment request: " + e.getMessage());
// Handle the error...
}
// Instantiate the client and send the prepare request
// Second argument is the originator ID, third one is the associated API key
Connect2payClient c2p = new Connect2payClient("https://provided.url", "123456", "GreatP4ssw0rd");
PaymentResponse response = null;
try {
response = c2p.preparePayment(request);
} catch (Exception e) {
logger.error("Ooops, an error occurred preparing the payment: " + e.getMessage());
// Handle the error...
}
if (response != null && ResultCode.SUCCESS.equals(response.getCode())) {
// Get the URL to redirect the user to
String redirectURL = response.getCustomerRedirectURL();
if (redirectURL != null) {
// Redirect the user towards this URL, this will display the payment page
}
} else {
// Handle the failure
}
}
}
// Process a payment of €39.99
PaymentRequest request = new PaymentRequest();
request.setOrderId("1234ABCD").setCurrency("EUR").setAmount(3999);
request.setShippingType(ShippingType.VIRTUAL);
request.setPaymentMode(PaymentMode.SINGLE);
// User will be redirected here when clicking on "Go back to merchant" button
request.setCtrlRedirectURL("http://my.website/somewhere");
// The payment page will do a callback on this URL after the payment is processed
request.setCtrlCallbackURL("http://my.website/payment-callback");
// Validate the request
try {
request.validate();
} catch (BadRequestException e) {
logger.error("Ooops, an error occurred validating the payment request: " + e.getMessage());
// Handle the error...
}
// Instantiate the client and send the prepare request
// Second argument is the originator ID, third one is the associated API key
Connect2payClient c2p = new Connect2payClient("https://connect2.payxpert.com", "123456", "GreatP4ssw0rd");
PaymentResponse response = null;
try {
response = c2p.preparePayment(request);
} catch (Exception e) {
logger.error("Ooops, an error occurred preparing the payment: " + e.getMessage());
// Handle the error...
}
if (response != null && ResultCode.SUCCESS.equals(response.getCode()) {
// Get the URL to redirect the user to
String redirectURL = response.getCustomerRedirectURL();
if (redirectURL != null) {
// Redirect the user towards this URL, this will display the payment page
}
} else {
// Handle the failure
}
const paymentPage = require("payxpert")("123456", "GreatP4ssw0rd").connect2pay;
const body = {
"shippingType": "virtual",
"paymentMode": "single",
"amount":500,
"currency":"EUR",
"orderID":"NODEJS TEST",
"ctrlRedirectURL":"http://my.website/somewhere",
"ctrlCallbackURL":"http://my.website/payment-callback"
};
const responseCreatePayment = await paymentPage.createPayment(body);
if (responseCreatePayment.code == "200") {
// Success
}
var client = new Connect2PayClient(OriginatorConfig.ORIGINATOR_ID, OriginatorConfig.ORIGINATOR_PASSWORD);
var request = client.NewRequestCreatePayment();
request.Data.orderID = "ABC-123456";
request.Data.paymentMethod = PaymentMethod.CREDIT_CARD;
request.Data.paymentMode = PaymentMode.SINGLE;
request.Data.shopperID = "RICH_SHOPPER";
request.Data.shippingType = ShippingType.VIRTUAL;
request.Data.operation = Operation.SALE;
request.Data.amount = 1500; // 15 EUR
request.Data.currency = "EUR";
request.Data.orderDescription = "Payment of €15.00";
request.Data.shopperFirstName = "RICH";
request.Data.shopperLastName = "SHOPPER";
request.Data.shopperAddress = "NA";
request.Data.shopperZipcode = "999111";
request.Data.shopperCity = "NA";
request.Data.shopperCountryCode = "GB";
request.Data.shopperPhone = "123-456";
request.Data.shopperEmail = "test@test.test";
request.Data.ctrlCustomData = "Give that back to me please !!";
request.Data.ctrlRedirectURL = "https://merchant.example.com/payment/redirect";
request.Data.ctrlCallbackURL = "https://merchant.example.com/payment/callback";
if (request.Data.Validate())
{
var response = await request.Send();
if (response.IsSuccessfull())
{
Console.WriteLine("Sale operation executed successfully");
Console.WriteLine("Merchant token: " + response.merchantToken);
Console.WriteLine("Customer redirect URL: " + request.getCustomerRedirectURL());
}
}