In this guide, we use our Card Storage solution to set up an MIT that is out of scope for SCA. To adhere to scheme rules, we first perform a 3D Secure 2 payment authentication (with Challenge Flag set to Mandated), even though we’re not charging the card before we store it.
Next, we follow the standard practice for card storage, which includes performing a verification (open-to-buy, OTB) before storing the card. We then charge the stored card, performing an MIT. In each step, we include the correct COF data. For more information, see our Credential on File article.
MITs explained
A merchant-initiated transaction (MIT) refers to a card payment made by a merchant without the customer being actively involved. This follows a transaction and an agreement made between the merchant and the customer in what is referred to as a customer-initiated transaction (CIT).
When flagged correctly, MITs are deemed as out of scope for Strong Customer Authentication (SCA) requirements under the Revised PSD2 within Europe and the United Kingdom. This allows MITs to be processed without any further required customer authentication and the associated friction that comes with it.
For an MIT to be considered out of scope for SCA:
- The initial CIT must have undergone 3D Secure 2 payment authentication, using the Challenge Mandated flag.
- All transactions must include the correct credential on file (COF) data. For more information, see our Credential on File article.
The following table describes the different types of MITs.
| Type | Description |
|---|---|
| Recurring | Transaction with a fixed amount but no fixed duration in which the merchant continues to process payments with the cardholder’s credentials until the cardholder cancels (for example, a subscription or a gym membership). |
| Installments | Transaction with a fixed amount and duration in which the merchant can’t process the cardholder’s credentials once this fixed period ends. Installments are paid at an agreed amount on the same day of each month (for example, paying for a kitchen appliance over 12 months interest free). |
| Oneoff | Unscheduled transaction with no fixed duration but with an agreed amount (for example, a travel card “top up” if the credit falls below a certain limit). |
Step 1: Payment authentication
In this guide, we assume that you’re already familiar with our 3D Secure 2 documentation and may have already integrated. In which case, you’ve already confirmed which version of 3D Secure the card supports and, conditionally, performed the Method URL step to allow the Issuer to gather data about the customer’s device.
The payment authentication confirms the customer’s billing and shipping address and performs checks using their browser data. Because this authentication initiates an MIT transaction sequence, we need to indicate to the Issuer that a challenge is mandated.
The following table lists the key data points to submit in the authentication message:
| Field | Value |
|---|---|
| Message Category | Payment Authentication (Must always be this value, even if you’re not charging the customer right away.) |
| Preference | Challenge Mandated |
GpApiConfig config = new GpApiConfig();
config.setAppId("app_id");
config.setAppKey("app_key");
config.setCountry("IE");
config.setChannel(Channel.CardNotPresent.getValue());
config.setChallengeNotificationUrl("https://ensi808o85za.x.pipedream.net/");
config.setMethodNotificationUrl("https://ensi808o85za.x.pipedream.net/");
config.setMerchantContactUrl("https://enp4qhvjseljg.x.pipedream.net/");
config.setEnableLogging(true);
ServicesContainer.configureService(config);
CreditCardData card = new CreditCardData();
card.setNumber("4263970000005262");
card.setExpMonth(9);
card.setExpYear(DateTime.now().getYear() + 1);
card.setCardHolderName("James Mason");
Address shippingAddress = new Address();
shippingAddress.setStreetAddress1("Apartment 852");
shippingAddress.setStreetAddress2("Complex 741");
shippingAddress.setStreetAddress3("House 963");
shippingAddress.setCity("Chicago");
shippingAddress.setPostalCode("5001");
shippingAddress.setState("IL");
shippingAddress.setCountryCode("840");
// Billing address
Address billingAddress = new Address();
billingAddress.setStreetAddress1("Apartment 852");
billingAddress.setStreetAddress2("Complex 741");
billingAddress.setStreetAddress3("House 963");
billingAddress.setCity("Chicago");
billingAddress.setState("IL");
billingAddress.setPostalCode("50001");
billingAddress.setCountryCode("840");
BrowserData browserData = new BrowserData();
browserData.setAcceptHeader("text/html,application/xhtml+xml,application/xml;q=9,image/webp,img/apng,*/*;q=0.8");
browserData.setColorDepth(ColorDepth.TwentyFourBit);
browserData.setIpAddress("123.123.123.123");
browserData.setJavaEnabled(true);
browserData.setJavaScriptEnabled(true);
browserData.setLanguage("en");
browserData.setScreenHeight(1080);
browserData.setScreenWidth(1920);
browserData.setChallengeWindowSize(ChallengeWindowSize.Windowed_600x400);
browserData.setTimezone("0");
browserData.setUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64, x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36");
String orderId = GenerationUtils.generateOrderId();
ThreeDSecure threeDS = new ThreeDSecure();
threeDS.setServerTransactionId ("AUT_d42e4d7a-4b02-48ad-84f5-cf62d07eb28a");
try {
ThreeDSecure threeDSecure =
Secure3dService
.initiateAuthentication(card, threeDS)
.withAmount(new BigDecimal("10.01"))
.withCurrency("EUR")
.withAuthenticationSource(AuthenticationSource.Browser)
.withMethodUrlCompletion(MethodUrlCompletion.Yes)
.withChallengeRequestIndicator(ChallengeRequestIndicator.ChallengeMandated)
.withAddressMatchIndicator(false)
.withReferenceNumber(orderId)
.withOrderCreateDate(DateTime.now())
.withAddress(shippingAddress, AddressType.Shipping)
.withAddress(billingAddress, AddressType.Billing)
.withMobileNumber("44", "123456789")
.withBrowserData(browserData)
.execute();
} catch (ApiException e) {
// TODO: add your error handling here
}
$config = new GpApiConfig();
$config->appId = 'app_id';
$config->appKey = 'app_key';
$config->country = 'IE';
$config->channel = Channel::CardNotPresent;
$config->challengeNotificationUrl = 'https://www.example.com/ChallengeNotification';
$config->methodNotificationUrl = 'https://www.example.com/MethodNotification';
$config->merchantContactUrl = 'https://www.example.com/about';
$config->requestLogger = new SampleRequestLogger(new Logger("logs"));
ServicesContainer::configureService($config);
$card = new CreditCardData();
$card->number = '4263970000005262';
$card->expMonth = '09';
$card->expYear = date('Y', strtotime('+1 year'));
$card->cardHolderName = "James Mason";
$shippingAddress = new Address();
$shippingAddress->streetAddress1 = "Apartment 852";
$shippingAddress->streetAddress2 = "Complex 741";
$shippingAddress->streetAddress3 = "House 963";
$shippingAddress->city = "Chicago";
$shippingAddress->postalCode = "50001";
$shippingAddress->state = 'IL';
$shippingAddress->countryCode = "840";
$billingAddress = new Address();
$billingAddress->streetAddress1 = "Apartment 852";
$billingAddress->streetAddress2 = "Complex 741";
$billingAddress->streetAddress3 = "House 963";
$billingAddress->city = "Chicago";
$billingAddress->state = "IL";
$billingAddress->postalCode = "50001";
$billingAddress->countryCode = "840";
$browserData = new BrowserData();
$browserData->acceptHeader = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8';
$browserData->colorDepth = ColorDepth::TWENTY_FOUR_BITS;;
$browserData->ipAddress = '123.123.123.123';
$browserData->javaEnabled = true;
$browserData->javaScriptEnabled = true;
$browserData->language = "en";
$browserData->screenHeight = 1080;
$browserData->screenWidth = 1920;
$browserData->challengWindowSize = ChallengeWindowSize::WINDOWED_600X400;
$browserData->timeZone = "0";
$browserData->userAgent = "Mozilla/5.0 (Windows NT 6.1; Win64, x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36";
$orderId = GenerationUtils::generateOrderId();
try {
$threeDS = new ThreeDSecure();
$threeDS->serverTransactionId = 'AUT_d42e4d7a-4b02-48ad-84f5-cf62d07eb28a';
$threeDSecure = Secure3dService::initiateAuthentication($card, $threeDS)
->withAmount('10.01')
->withCurrency('EUR')
->withAuthenticationSource(AuthenticationSource::BROWSER)
->withMethodUrlCompletion(MethodUrlCompletion::YES)
->withChallengeRequestIndicator(ChallengeRequestIndicator::CHALLENGE_MANDATED)
->withAddressMatchIndicator(false)
->withReferenceNumber($orderId)
->withOrderCreateDate(date('Y-m-d H:i:s'))
->withAddress($shippingAddress, AddressType::SHIPPING)
->withAddress($billingAddress, AddressType::BILLING)
->withMobileNumber('44', '123456789')
->withBrowserData($browserData)
->execute();
} catch (ApiException $e) {
// TODO: add your error handling here
}
GpApiConfig config = new GpApiConfig();
config.AppId = "app_id";
config.AppKey = "app_key";
config.Country = "IE";
config.Channel = Channel.CardNotPresent;
config.ChallengeNotificationUrl = "https://www.example.com/ChallengeNotification";
config.MethodNotificationUrl = "https://www.example.com/MethodNotification";
config.MerchantContactUrl = "https://www.example.com/about";
config.RequestLogger = new RequestConsoleLogger();
ServicesContainer.ConfigureService(config);
CreditCardData card = new CreditCardData();
card.Number = "4263970000005262";
card.ExpMonth = DateTime.Now.Month;
card.ExpYear = DateTime.Now.Year + 1;
card.CardHolderName = "James Mason";
Address shippingAddress = new Address();
shippingAddress.StreetAddress1 = "Apartment 852";
shippingAddress.StreetAddress2 = "Complex 741";
shippingAddress.StreetAddress3 = "House 963";
shippingAddress.City = "Chicago";
shippingAddress.PostalCode = "50001";
shippingAddress.State = "IL";
shippingAddress.CountryCode = "840";
Address billingAddress = new Address();
billingAddress.StreetAddress1 = "Apartment 852";
billingAddress.StreetAddress2 = "Complex 741";
billingAddress.StreetAddress3 = "House 963";
billingAddress.City = "Chicago";
billingAddress.State = "IL";
billingAddress.PostalCode = "50001";
billingAddress.CountryCode = "840";
BrowserData browserData = new BrowserData();
browserData.AcceptHeader = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
browserData.ColorDepth = ColorDepth.TWENTY_FOUR_BITS; ;
browserData.IpAddress = "123.123.123.123";
browserData.JavaEnabled = true;
browserData.JavaScriptEnabled = true;
browserData.Language = "en";
browserData.ScreenHeight = 1080;
browserData.ScreenWidth = 1920;
browserData.ChallengeWindowSize = ChallengeWindowSize.WINDOWED_600X400;
browserData.Timezone = "0";
browserData.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64, x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36";
var orderId = Guid.NewGuid().ToString();
try
{
ThreeDSecure threeDS = new ThreeDSecure();
threeDS.ServerTransactionId = "AUT_d42e4d7a-4b02-48ad-84f5-cf62d07eb28a";
ThreeDSecure threeDSecure = Secure3dService.InitiateAuthentication(card, threeDS)
.WithAmount(10.01m)
.WithCurrency("EUR")
.WithAuthenticationSource(AuthenticationSource.BROWSER)
.WithMethodUrlCompletion(MethodUrlCompletion.YES)
.WithChallengeRequestIndicator(ChallengeRequestIndicator.CHALLENGE_MANDATED)
.WithAddressMatchIndicator(false)
.WithReferenceNumber(orderId)
.WithOrderCreateDate(DateTime.Now)
.WithAddress(shippingAddress, AddressType.Shipping)
.WithAddress(billingAddress, AddressType.Billing)
.WithMobileNumber("44", "123456789")
.WithBrowserData(browserData)
.Execute();
}
catch (ApiException e)
{
// TODO: add your error handling here
}
curl --location --request POST 'https://apis.sandbox.globalpay.com/ucp/authentications/AUT_d42e4d7a-4b02-48ad-84f5-cf62d07eb28a/initiate' \
--header 'X-GP-Version: 2021-03-22' \
--header 'Authorization: Bearer TrAtA2UcxiCOj097b5d1P4rj1BKx' \
--header 'Content-Type: application/json' \
--data-raw '{
"three_ds": {
"source": "BROWSER",
"preference": "CHALLENGE_MANDATED",
"message_category": "PAYMENT"
},
"account_id": "TRA_4d49f5d4e1b84ea4a28c8902a8538375",
"channel": "CNP",
"country": "IE",
"method_url_completion_status": "YES",
"payment_method": {
"name": "James Mason",
"entry_mode": "ECOM",
"card": {
"number": "4263970000005262",
"expiry_month": "09",
"expiry_year": "22"
}
},
"order": {
"time_created_reference": "2019-04-26T10:19:32.552327Z",
"amount": "1001",
"currency": "EUR",
"reference": "3400dd37-101d-4940-be15-3c963b6109b3",
"address_match_indicator": "false",
"shipping_address": {
"line1": "Apartment 852",
"line2": "Complex 741",
"line3": "House 963",
"city": "Chicago",
"postal_code": "50001",
"state": "IL",
"country": "840"
}
},
"payer": {
"billing_address": {
"line1": "Apartment 852",
"line2": "Complex 741",
"line3": "House 963",
"city": "Chicago",
"postal_code": "50001",
"state": "IL",
"country": "840"
},
"mobile_phone": {
"country_code": "44",
"subscriber_number": "123456789"
}
},
"browser_data": {
"accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"color_depth": "TWENTY_FOUR_BITS",
"ip": "123.123.123.123",
"java_enabled": "true",
"javascript_enabled": "true",
"language": "en-US",
"screen_height": "1080",
"screen_width": "1920",
"challenge_window_size": "FULL_SCREEN",
"timezone": "0",
"user_agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
},
"merchant_contact_url": "https://www.example.com/about"
}'
Step 2: Verify the card
With a verification request, or OTB, you can check if a card is still valid and active without actually processing a payment against it. The outcome of the payment authentication tells us this as well. However, with the OTB, you can also check the security code and address before storing the card.
In this request, we provide the COF data, including the type of agreement between the merchant and customer as well as the transaction sequence - FIRST. We also need to flag this as a CIT. By including all this data, you’ll set up the card for future MITs. The verification will return a brand reference (also known as Scheme Reference Data, or SRD) in the response, which is also important for subsequent transactions.
GpApiConfig config = new GpApiConfig();
config.setAppId("app_id");
config.setAppKey("app_key");
config.setCountry("IE");
config.setChannel(Channel.CardNotPresent.getValue());
ServicesContainer.configureService(config);
CreditCardData card = new CreditCardData();
card.setNumber("4263970000005262");
card.setExpMonth(9);
card.setExpYear(DateTime.now().getYear() + 1);
card.setCardHolderName("James Mason");
card.setCvn("852");
Address billingAddress = new Address();
billingAddress.setStreetAddress1("Apartment 852");
billingAddress.setStreetAddress2("Complex 741");
billingAddress.setStreetAddress3("House 963");
billingAddress.setCity("Chicago");
billingAddress.setPostalCode("5001");
billingAddress.setState("IL");
billingAddress.setCountryCode("840");
String orderId = GenerationUtils.generateOrderId();
Transaction response = card.verify()
.withCurrency("EUR")
.withClientTransactionId(orderId)
.withAddress(billingAddress, AddressType.Billing)
.execute();
String cardBrandReference = response.getCardBrandTransactionId();
$config = new GpApiConfig();
$config->appId = 'app_id';
$config->appKey = 'app_key';
$config->country = 'IE';
$config->channel = Channel::CardNotPresent;
ServicesContainer::configureService($config);
$card = new CreditCardData();
$card->number = '4263970000005262';
$card->expMonth = '09';
$card->expYear = date('Y', strtotime('+1 year'));
$card->cardHolderName = "James Mason";
$card->cvn = '852';
$billingAddress = new Address();
$billingAddress->streetAddress1 = "Apartment 852";
$billingAddress->streetAddress2 = "Complex 741";
$billingAddress->streetAddress3 = "House 963";
$billingAddress->city = "Chicago";
$billingAddress->state = "IL";
$billingAddress->postalCode = "50001";
$billingAddress->countryCode = "840";
$orderId = GenerationUtils::generateOrderId();
$response = $card->verify()
->withCurrency('EUR')
->withClientTransactionId($orderId)
->withAddress($billingAddress, AddressType::BILLING)
->execute();
$cardBrandReference = $response->cardBrandTransactionId;
GpApiConfig config = new GpApiConfig();
config.AppId = "app_id";
config.AppKey = "app_key";
config.Country = "IE";
config.Channel = Channel.CardNotPresent;
ServicesContainer.ConfigureService(config);
CreditCardData card = new CreditCardData();
card.Number = "4263970000005262";
card.ExpMonth = DateTime.Now.Month;
card.ExpYear = DateTime.Now.Year + 1;
card.CardHolderName = "James Mason";
card.Cvn = "852";
Address billingAddress = new Address();
billingAddress.StreetAddress1 = "Apartment 852";
billingAddress.StreetAddress2 = "Complex 741";
billingAddress.StreetAddress3 = "House 963";
billingAddress.City = "Chicago";
billingAddress.State = "IL";
billingAddress.PostalCode = "50001";
billingAddress.CountryCode = "840";
var orderId = Guid.NewGuid().ToString();
var response = card.Verify()
.WithCurrency("EUR")
.WithClientTransactionId(orderId)
.WithAddress(billingAddress, AddressType.Billing)
.Execute();
var cardBrandReference = response.CardBrandTransactionId;
curl --location --request POST 'https://apis.sandbox.globalpay.com/ucp/verifications' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer oaFwF4Y4KJADG1wfvO4x254F9NEh' \
--header 'Accept: application/json' \
--header 'X-GP-Version: 2021-03-22' \
--data-raw '{
"account_id": "TRA_4d49f5d4e1b84ea4a28c8902a8538375",
"channel": "CNP",
"currency": "EUR",
"reference": "1457974b-1f3f-40dd-8dd1-c6010a5aabbe",
"country": "IE",
"initiator": "PAYER",
"stored_credential": {
"model": "UNSCHEDULED",
"sequence": "FIRST"
},
"payment_method": {
"first_name": "James",
"last_name": "Mason",
"entry_mode": "ECOM",
"card": {
"number": "4263970000005262",
"expiry_month": "09",
"expiry_year": "22",
"cvv": "852",
"avs_address": "Flat 123",
"avs_postal_code": "50001"
}
}
}'
Step 3: Store the card
Now that we’ve successfully processed a payment authentication and validated the card, we can store it for future transactions. Our Card Storage solution returns a Payment Method ID (or token), which you can store with the brand reference from Step 2.
GpApiConfig config = new GpApiConfig();
config.setAppId("app_id");
config.setAppKey("app_key");
config.setCountry("IE");
config.setChannel(Channel.CardNotPresent.getValue());
ServicesContainer.configureService(config);
CreditCardData card = new CreditCardData();
card.setNumber("4263970000005262");
card.setExpMonth(9);
card.setExpYear(DateTime.now().getYear() + 1);
card.setCardHolderName("James Mason");
String reference = GenerationUtils.generateOrderId();
Transaction response = card.tokenize(true, PaymentMethodUsageMode.MULTIPLE)
.withClientTransactionId(reference)
.execute();
String paymentToken = response.getToken(); // "PMT_850924e2-d2bd-4724-bb59-12ae1cec392d"
$config = new GpApiConfig();
$config->appId = 'app_id';
$config->appKey = 'app_key';
$config->country = 'IE';
$config->channel = Channel::CardNotPresent;
ServicesContainer::configureService($config);
$card = new CreditCardData();
$card->number = '4263970000005262';
$card->expMonth = '09';
$card->expYear = date('Y', strtotime('+1 year'));
$card->cardHolderName = "James Mason";
$reference = GenerationUtils::generateOrderId();
$response = $card->tokenize()
->withClientTransactionId($reference)
->execute();
$paymentToken = $response->token; // "PMT_850924e2-d2bd-4724-bb59-12ae1cec392d"
GpApiConfig config = new GpApiConfig();
config.AppId = "oDVjAddrXt3qPJVPqQvrmgqM2MjMoHQS";
config.AppKey = "DHUGdzpjXfTbjZeo";
config.Country = "IE";
config.Channel = Channel.CardNotPresent;
ServicesContainer.ConfigureService(config);
CreditCardData card = new CreditCardData();
card.Number = "4263970000005262";
card.ExpMonth = DateTime.Now.Month;
card.ExpYear = DateTime.Now.Year + 1;
card.CardHolderName = "James Mason";
var paymentToken = card.Tokenize(); // "PMT_850924e2-d2bd-4724-bb59-12ae1cec392d"
curl --location --request POST 'https://apis.sandbox.globalpay.com/ucp/payment-methods' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer oaFwF4Y4KJADG1wfvO4x254F9NEh' \
--header 'Accept: application/json' \
--header 'X-GP-Version: 2021-03-22' \
--data-raw '{
"account_id": "TKA_b90e546b11a84f65b9052e99fc317c5d",
"reference": "f7981ab2-e758-41f0-9e8f-59ca7ce075eb",
"usage_mode": "MULTIPLE",
"card": {
"number": "4263970000005262",
"expiry_month": "09",
"expiry_year": "22"
}
}'
Step 4: Charging the card
We’re now ready to process our MIT. This time in the transaction request, we pass the relevant Payment Method ID instead of the card data. We also flag the initiator as a merchant and pass in the correct sequence and brand reference.
GpApiConfig config = new GpApiConfig();
config.setAppId("app_id");
config.setAppKey("app_key");
config.setCountry("IE");
config.setChannel(Channel.CardNotPresent.getValue());
ServicesContainer.configureService(config);
CreditCardData card = new CreditCardData();
card.setNumber("4263970000005262");
card.setExpMonth(9);
card.setExpYear(DateTime.now().getYear() + 1);
card.setCardHolderName("James Mason");
String reference = GenerationUtils.generateOrderId();
StoredCredential storeCredentials = new StoredCredential();
storeCredentials.setInitiator(StoredCredentialInitiator.Merchant);
storeCredentials.setType(StoredCredentialType.Unscheduled);
storeCredentials.setSequence(StoredCredentialSequence.Subsequent);
CreditCardData tokenizedCard = new CreditCardData();
tokenizedCard.setToken(paymentToken); // the value of payment token value from step 3
Transaction transaction = tokenizedCard.charge(10)
.withCurrency("EUR")
.withStoredCredential(storeCredentials)
.withClientTransactionId(reference)
.withCardBrandStorage(StoredCredentialInitiator.Merchant, cardBrandReference) // cardBrandReference is from step 2
.execute();
String responseCode = transaction.getResponseCode(); //SUCCESS
String $transactionStatus = transaction.getResponseMessage(); //CAPTURED
$config = new GpApiConfig();
$config->appId = 'app_id';
$config->appKey = 'app_key';
$config->country = 'IE';
$config->channel = Channel::CardNotPresent;
ServicesContainer::configureService($config);
$card = new CreditCardData();
$card->number = '4263970000005262';
$card->expMonth = '09';
$card->expYear = date('Y', strtotime('+1 year'));
$card->cardHolderName = "James Mason";
$reference = GenerationUtils::generateOrderId();
$storeCredentials = new StoredCredential();
$storeCredentials->initiator = StoredCredentialInitiator::MERCHANT;
$storeCredentials->type = StoredCredentialType::UNSCHEDULED;
$storeCredentials->sequence = StoredCredentialSequence::SUBSEQUENT;
$tokenizedCard = new CreditCardData();
$tokenizedCard->token = $paymentToken; // the value of payment token value from step 3
$transaction = $tokenizedCard->charge(10)
->withCurrency("EUR")
->withStoredCredential($storeCredentials)
->withClientTransactionId($reference)
->withCardBrandStorage(StoredCredentialInitiator::MERCHANT, $cardBrandReference) // $cardBrandReference is from step 2
->execute();
$responseCode = $transaction->responseCode; //SUCCESS
$transactionStatus = $transaction->responseMessage; //CAPTURED
GpApiConfig config = new GpApiConfig();
config.AppId = "app_id";
config.AppKey = "app_key";
config.Country = "IE";
config.Channel = Channel.CardNotPresent;
ServicesContainer.ConfigureService(config);
CreditCardData card = new CreditCardData();
card.Number = "4263970000005262";
card.ExpMonth = DateTime.Now.Month;
card.ExpYear = DateTime.Now.Year + 1;
card.CardHolderName = "James Mason";
var reference = Guid.NewGuid().ToString();
var storeCredentials = new StoredCredential();
storeCredentials.Initiator = StoredCredentialInitiator.Merchant;
storeCredentials.Type = StoredCredentialType.Unscheduled;
storeCredentials.Sequence = StoredCredentialSequence.Subsequent;
var tokenizedCard = new CreditCardData();
tokenizedCard.Token = paymentToken; // the value of payment token value from step 3
var transaction = tokenizedCard.Charge(10)
.WithCurrency("EUR")
.WithStoredCredential(storeCredentials)
.WithClientTransactionId(reference)
.WithCardBrandStorage(StoredCredentialInitiator.Merchant, cardBrandReference) // $cardBrandReference is from step 2
.Execute();
var responseCode = transaction.ResponseCode; //SUCCESS
var transactionStatus = transaction.ResponseMessage; //CAPTURED
curl --location --request POST 'https://apis.sandbox.globalpay.com/ucp/transactions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer oaFwF4Y4KJADG1wfvO4x254F9NEh' \
--header 'Accept: application/json' \
--header 'X-GP-Version: 2021-03-22' \
--data-raw '{
"account_id": "TRA_4d49f5d4e1b84ea4a28c8902a8538375",
"channel": "CNP",
"amount": "100",
"currency": "EUR",
"reference": "36527151",
"country": "IE",
"initiator": "MERCHANT",
"stored_credential": {
"model": "UNSCHEDULED",
"sequence": "SUBSEQUENT"
},
"payment_method": {
"name": "James Mason",
"entry_mode": "ECOM",
"id": "PMT_850924e2-d2bd-4724-bb59-12ae1cec392d",
"card": {
"brand_reference": "uGfCzJQ8ZSP17j9J"
}
}
}'