Universal Card Storage

Universal card storage feature allows merchants to get payments from their customer's saved cards.

Payment process with saved cards

1- To get the necessary information, you need to send email and gsmNumber information to this service. In the response, you can understand if your customer has a saved card or not. This service returns you a response including scriptType tag. You can see scriptType values below,

  • CONSUMER_WITH_CARD_EXIST:   This value means that the customer has already a stored card.
  • UCS_CONSENT:   This means that customer does not have a saved card.

2- If your customer has a stored card(scriptType:CONSUMER_WITH_CARD_EXIST), please follow the steps below

Script parameter in the response of UCS service should be printed in the webpage. This javascript loads related items for payments without card information.

  • "<script type=\"text/javascript\">if (typeof iyziUcsInit == 'undefined') {var iyziUcsInit = {\"baseUrl\":\"https://sandbox-api.iyzipay.com\", \"buyerProtectedConsumer\":false,\"ucsToken\":\"3f971db9-897c-4c74-aa29-ed9b40644b12\",\"scriptType\":\"CONSUMER_WITH_CARD_EXIST\",\"buyerProtectedMerchant\":false,\"maskedGsmNumber\":\"+90********31\",\"gsmNumber\":\"+905557378631\",\"merchantName\":\"Sandbox Merchant Name - 58892\", createTag: function () {var iyziUcsJSTag = document.createElement('script'); iyziUcsJSTag.setAttribute('src', 'https://sandbox-static.iyzipay.com/checkoutform/v2/bundle.js?v=1575919444317'); document.head.appendChild(iyziUcsJSTag);}};if (typeof iyziInit == 'undefined') { iyziUcsInit.createTag(); }}</script>"

In your checkout form, put this div line to the related place

  • <div id="ucs-cards"></div>

After you print the javascript and the div above, your website will load the screen below into the ucs-cards div. If your customer continues the process, he/she will be asked to make an OTP-SMS to access the stored cards.

At this step, your web page also loads a javascript object called universalCardStorage. You can find detailed information about this object in next steps.

After your customer passes the OTP, the screen is updated as below and it shows the saved cards of your customer.

You can think this page as a form. You can put a button to a related area and whenever your customer clicks the button, you can check the values of universalCardStorage object. The payment flow can be processed according to values in universalCardStorage.

universalCardStorage: This javascript object is loaded as soon as you called the UCS service. To be able to follow all process you can check this object if any action has been taken on your payment form. It has 4 parameters. If your customer already has stored cards, registerConsumerCard parameter will be True. Otherwise, by default registerConsumerCard parameter will be false.

If your customer already has a saved card, there are 3 conditions that you may follow

  • Your customer has a saved card but did not pass the OTP - sms verification (This means the customer did not see his/hre saved cards yet.)
    universalCardStorage: {registerConsumerCard: true, gsmNumber: "+905557378631", consumerToken: undefined, cardToken: undefined}
    If your form is submitted at this step, you can understand that your customer does not want to use a sotred card. You can check the object universalCardStorage. You can see that consumerToken and cardToken values in this object are undefined. So please process the payment with the form that you already use.

  • The customer has a saved card and passed the OTP SMS verification (Customer sees the list of cards in the next screen )
    universalCardStorage: {registerConsumerCard: true, gsmNumber: "+905557378631", consumerToken: "31ad9-2335a3b", cardToken: "ca9c8360-ca08"}
    In this case, if customer submits the form, consumerToken and cardToken values are defined in universalCardStorage object. You can pass these values to your backend and use them in a payment request. This will provide you to get payments from saved cards. Instead of sending card information, passing consumerToken, cardToken and ucsToken information will be enough to use a saved card.(ucsToken value is available in UCS init response).

  • Customer has saved cards, passes the OTP-SMS and wants to use a new card
    universalCardStorage: {registerConsumerCard: true, gsmNumber: "+905557378631", consumerToken: "31ad9-2335a3b", cardToken: undefined}
    As soon as the form is submitted, when you check universalCardStorage parameters, if consumerToken is True and the cardToken is undefined, this means that the customer wants to pay with a new card and save the card at the time of payment. You can continue with your payment form however you need to send one more parameter to save the card. If you send registerConsumerCard parameter as true, the card will be saved.
If Customer does not have a saved card

If the value of scriptType parameter in UCS service response is UCS_CONSENT then you can understand that your customer does not have a saved card in iyzico ecosystem. At the same time registerConsumerCard parameter in the universalCardStorage object will be received as False. At this step, if you want to save the card, you need to give information about aggreements and the customer should accept the aggreement. To do this, adding below "div" will be enough to show the agreement and informative text provided by iyzico.

You should also print javascript code coming from "script" parameter

Put mentioned "div" to the related area of your payment form

  • <div id="ucs-cards"></div>

Your customer will see the screen below. If your customer checks the checkbox, registerConsumerCard parameter in universalCardStorage javascript object will become True. So as soon as your payment form is submitted, you can check this javascript value(universalCardStorage.registerConsumerCard). If it is True, this means that your customer confirmed the aggrement. So the card can be saved at the time of payment.

.

Not: Every UCSToken and universalCardStorage object is valid for 30 minutes. If they are not used within 30 minutes. you need to reinitate the UCS init request.

**Parameters to be sent to the service are as follows:

UCS init service**

Parameter Type Mandatory Description
locale string no Language (default: tr)
conversationId string no If set, conversation ID to match request and response
email string yes Email address of card owner
gsmNumber string yes Gsm number of card owner


Parameters to be returned from the service are as follows:

Parametre ismi Tip Açıklama
status string Service response result (success / failure)
script string Javascript code for retrieving the stored cards. It should be printed in the web page
scriptType string Specifies whether the customer has stored card or not . It can be CONSUMER_WITH_CARD_EXIST and UCS_CONSENT
merchantName string Merchant name.
maskedGsmNumber string Masked gsm number of customer
gsmNumber string Customer's gsm number
buyerProtectedConsumer boolean if customer has protected payments, it can be learnt from this tag
buyerProtectedMerchant boolean if protected payment is activated for the merchant, this value becomes true
errorCode string Error code if service response status is failure
errorMessage string Error message if service response status is failure
errorGroup string Error group if service response status is failure
locale string Language (default: tr)
systemTime integer Response system timestamp value
conversationId string If set, conversation ID to match request and response

// create request class
$request = new \Iyzipay\Request\UCSInitializeRequest();
$request->setConversationId("1234566");
$request->setLocale("tr");
$request->setEmail("email@iyzico.com");
$request->setGsmNumber("+905557378631");

// make request
$result = \Iyzipay\Model\UCSInitialize::create($request,Config::options());
//Request
{
    "locale": "tr",
    "conversationId": "123456",    
    "email": "email@iyzico.com",
    "gsmNumber": "+905557378631"
}

//Response
{
  "buyerProtectedConsumer": false,
  "buyerProtectedMerchant": false,
  "gsmNumber": "+905533378631",
  "locale": "tr",
  "maskedGsmNumber": "+90********31",
  "merchantName": "Test Name - 58892",
  "script": "<script type=\"text/javascript\">if (typeof iyziUcsInit == 'undefined') {var iyziUcsInit = {\"baseUrl\":\"https://sandbox-api.iyzipay.com\", \"ucsToken\":\"32b30114-85dd-47a5-a2bd-9071c95bc389\",\"scriptType\":\"UCS_CONSENT\",\"buyerProtectedMerchant\":false,\"maskedGsmNumber\":\"+90********31\",\"gsmNumber\":\"+905533378631\",\"merchantName\":\"Sandbox Merchant Name - 58892\", createTag: function () {var iyziUcsJSTag = document.createElement('script'); iyziUcsJSTag.setAttribute('src', 'https://sandbox-static.iyzipay.com/checkoutform/v2/bundle.js?v=1575969451615'); document.head.appendChild(iyziUcsJSTag);}};if (typeof iyziInit == 'undefined') { iyziUcsInit.createTag(); }}</script>",
  "scriptType": "UCS_CONSENT",
  "status": "success",
  "systemTime": 1575969451615,
  "ucsToken": "32b30114-a2bd-9071c95bc389"
}

Sameple Codes

SENDING PAYMENT REQUEST WITH STORED CARD

Parameters to be sent to the service are as follows:

Input Name Type Mandatory Description
price Decimal Yes Total amount of basket. The sum of basket items’ amount must be equal to the price of basket
paidPrice Decimal Yes Final amount (including installment fee) that will be charged to customer’s card
currency String Yes Currency (default: TRY). Alternatively, you can set USD, EUR, GBP and IRR
installment Integer Yes Installment value. For single installment payments it should be 1 (valid values: 1, 2, 3, 6, 9, 12)
cardToken String Yes Card Token received from UCS service. It can be accessed from universalCardStorage object
consumerToken String Yes Consumer Token received from UCS service. It can be accessed from universalCardStorage object
ucsToken String Yes UCS Token received from UCS service. It can be accessed from UCS init response
id(Buyer) String Yes ID of buyer.
name(Buyer) String Yes Name of buyer
surname(Buyer) String Yes Surname of buyer
identityNumber(Buyer) String Yes Identity number of buyer. TCKN for Turkish merchants, passport number for foreign merchants
city(Buyer) String Yes City of buyer
country(Buyer) String Yes Country of buyer
email(Buyer) String Yes Email of buyer
ip(Buyer) String Yes IP of buyer
registrationAddress(Buyer) String Yes Registration address of buyer
contactName(BillingAddress) String Yes Contact name of billing address
city(BillingAddress) String Yes City name of billing address
country(BillingAddress) String Yes Country name of billing address
address(BillingAddress) String Yes Address details of billing address
contactName(ShippingAddress) String Yes Contact name of shipping adress. If one of the itemType in basket is PHYSICAL, then this parameter will be mandatory
city(ShippingAddress) String Yes City name of shipping address. If one of the itemType in basket is PHYSICAL, then this parameter will be mandatory
country(ShippingAddress) String Yes Country name of shipping address. If one of the itemType in basket is PHYSICAL, then this parameter will be mandatory
address(ShippingAddress) String Yes Address details of shipping address. If one of the itemType in basket is PHYSICAL, then this parameter will be mandatory
id(BasketItems) String Yes Basket Item ID
itemType(BasketItems) String Yes Item Type. Valid values are PHYSICAL,VIRTUAL
price(BasketItems) Decimal Yes Price value for each item. Must be greater than zero
name(BasketItems) String Yes Name of the item in the basket
category1(BasketItems) String Yes Category 1 for item in the basket
zipCode(Buyer) String No Zip code of buyer
zipCode(ShippingAddress) String No Zip code of shipping address
zipCode(BillingAddress) String No Zip code of billing address
category2(BasketItems) String No Category 2 for item in the basket
gsmNumber(Buyer) String No GSM number of buyer
subMerchantPrice(BasketItem) Decimal No Payout amount to subMerchant of each item. Must be greater than zero. Mandatory value for marketplace solution
subMerchantKey(BasketItem) String No Submerchant ID value. Mandatory value for marketplace solution
registerCard Integer No Parameter that shows card details will store or not. Default value is 0 and valid values are 0 or 1
cardAlias Integer No If registerCard value is 1 cardAlias can send within request.
registrationDate(Buyer) String No Registration date of buyer. Format should be “2015-09-17 23:45:06”
lastLoginDate(Buyer) String No Last login date of buyer. Format should be “2015-09-17 23:45:06”
locale String No Language (default: tr)
conversationId String No Conversation ID to match request and response
basketId String No Merchant's basket ID
paymentChannel String No Payment channel. Valid values are WEB, MOBILE, MOBILE_WEB, MOBILE_IOS, MOBILE_ANDROID, MOBILE_WINDOWS, MOBILE_TABLET, MOBILE_PHONE
paymentGroup String No Payment group (default: PRODUCT). Valid values are PRODUCT, LISTING, SUBSCRIPTION
paymentSource String No Payment source. Valid values are SHOPIFY, MAGENTO, PRESTASHOP, WOOCOMMERCE, OPENCART

Response

Parameters to be returned from the service are as follows:

Output Name Type Description
status String Service response result (success / failure)
errorCode String Error code if service response status is failure
errorMessage String Error message if service response status is failure
errorGroup String Error group if service response status is failure
locale String Language (default: tr)
systemTime Long Response system timestamp value
conversationId String If set, conversation ID to match request and response
paymentId String ID of the payment. Merchants should keep payment ID in their system (this ID will be used for cancel requests)
price Decimal Total amount of basket. The sum of basket items’ amount must be equal to the price of basket
paidPrice Decimal Final amount (including installment fee) that will be charged to customer’s card. Merchants should store this value in their system
currency String Currency of request
installment Integer Installment number of payment, for single payments it returns 1. Valid values are 1, 2, 3, 6, 9, 12
basketId String Merchant's basket ID
binNumber String First 6 digit of card
cardAssociation String Valid values are VISA, MASTER_CARD, AMERICAN_EXPRESS, TROY
cardFamily String Valid values are Bonus, Axess, World, Maximum, Paraf, CardFinans, Advantage
cardType String Valid values are CREDIT_CARD, DEBIT_CARD, PREPAID_CARD
fraudStatus Integer Fraud risk status for payment request (0 for review / 1 for accept)
iyziCommissionFee Decimal iyzico commission fee for payment transaction
iyziCommissionRateAmount Decimal iyzico commission rate amount for payment transaction
merchantCommissionRate Decimal Merchant commission rate (e.g. price=100 & paidPrice=110, then merchant commission rate = 10)
merchantCommissionRateAmount Decimal Merchant commission rate amount (e.g. price=100 & paidPrice=110, then merchant commission rate amount = 10)
paymentTransactionId (ItemTransactions) String ID of basket item. Merchants should keep payment ID in their system (this ID will be used for cancel requests)
itemId(ItemTransactions) String Item ID of each item in basket
price(ItemTransactions) Decimal Item price of each item in basket
paidPrice(ItemTransactions) Decimal Captured amount from card based on each item. Merchants should keep paidPrice in their system
transactionStatus (ItemTransactions) Integer Status of a payment transaction. (0 for waiting / -1 for rejected by fraud / 1 for waiting for approval / 2 for approved
blockageRate(ItemTransactions) Decimal Blockage rate based on each item.
blockageRateAmountMerchant(ItemTransactions) Decimal Blockage rate amount for merchant based on each item
blockageResolvedDate(ItemTransactions) String Blockage resolve date based on each item. Date format should be “2015-10-19 14:36:52”
iyziCommissionFee(ItemTransactions) Decimal iyzico commission fee based on each item
iyziCommissionRateAmount(ItemTransactions) Decimal iyzico commission rate amount based on each item
merchantCommissionRate(ItemTransactions) Decimal Merchant commission rate (e.g. price=100 & paidPrice=110, then merchant commission rate = 10)
merchantCommissionRateAmount(ItemTransactions) Decimal Merchant commission rate amount (e.g. price=100 & paidPrice=110, then merchant commission rate amount = 10)
merchantPayoutAmount(ItemTransactions) Decimal Payout amount for each item transaction. This is the amount that remains after after substracting iyzicoCommissionRateAmount, iyzicoCommissionFee and blockageRateAmountMerchant from paidPrice(ItemTransactions)
paidPrice(ItemTransactions)(convertedPayout) Decimal Converted charged amount to card based on each item. Merchants should keep paidPrice in their system.
iyziCommissionFee(ItemTransactions)(convertedPayout) Decimal Converted iyzico commission fee based on each item
iyziCommissionRateAmount(ItemTransactions)(convertedPayout) Decimal Converted iyzico commission rate amount based on each item
blockageRateAmountMerchant(ItemTransactions)(convertedPayout) Decimal Converted blockage rate amount for merchant based on each item
merchantPayoutAmount(ItemTransactions)(convertedPayout) Decimal Converted payout amount for each item transaction. This the amount that remains after substracting iyzicoCommissionRateAmount, iyzicoCommissionFee and blockageRateAmountMerchant from paidPrice(ItemTransactions)
iyziConversationRate(ItemTransactions)(convertedPayout) Decimal iyzico conversation rate
iyziConversationRateAmount(ItemTransactions)(convertedPayout) Decimal iyzico conversation rate amount
currency(ItemTransactions)(convertedPayout) String Currency for payout conversion

$request = new \Iyzipay\Request\CreatePaymentRequest();
$request->setLocale(\Iyzipay\Model\Locale::TR);
$request->setConversationId("123456789");
$request->setPrice("1");
$request->setPaidPrice("1.2");
$request->setCurrency(\Iyzipay\Model\Currency::TL);
$request->setInstallment(1);
$request->setBasketId("B67832");
$request->setPaymentChannel(\Iyzipay\Model\PaymentChannel::WEB);
$request->setPaymentGroup(\Iyzipay\Model\PaymentGroup::PRODUCT);
$paymentCard = new \Iyzipay\Model\PaymentCard();
$paymentCard->setUcsToken("sampleToken");
$paymentCard->setConsumerToken("55287-9000-00000-08");
$paymentCard->setCardToken("12332-3523-345-234-56456");
$request->setPaymentCard($paymentCard);
$buyer = new \Iyzipay\Model\Buyer();
$buyer->setId("BY789");
$buyer->setName("John");
$buyer->setSurname("Doe");
$buyer->setGsmNumber("+905350000000");
$buyer->setEmail("email@email.com");
$buyer->setIdentityNumber("74300864791");
$buyer->setLastLoginDate("2015-10-05 12:43:35");
$buyer->setRegistrationDate("2013-04-21 15:12:09");
$buyer->setRegistrationAddress("Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1");
$buyer->setIp("85.34.78.112");
$buyer->setCity("Istanbul");
$buyer->setCountry("Turkey");
$buyer->setZipCode("34732");
$request->setBuyer($buyer);
$shippingAddress = new \Iyzipay\Model\Address();
$shippingAddress->setContactName("Jane Doe");
$shippingAddress->setCity("Istanbul");
$shippingAddress->setCountry("Turkey");
$shippingAddress->setAddress("Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1");
$shippingAddress->setZipCode("34742");
$request->setShippingAddress($shippingAddress);
$billingAddress = new \Iyzipay\Model\Address();
$billingAddress->setContactName("Jane Doe");
$billingAddress->setCity("Istanbul");
$billingAddress->setCountry("Turkey");
$billingAddress->setAddress("Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1");
$billingAddress->setZipCode("34742");
$request->setBillingAddress($billingAddress);
$basketItems = array();
$firstBasketItem = new \Iyzipay\Model\BasketItem();
$firstBasketItem->setId("BI101");
$firstBasketItem->setName("Binocular");
$firstBasketItem->setCategory1("Collectibles");
$firstBasketItem->setCategory2("Accessories");
$firstBasketItem->setItemType(\Iyzipay\Model\BasketItemType::PHYSICAL);
$firstBasketItem->setPrice("0.3");
$basketItems[0] = $firstBasketItem;
$secondBasketItem = new \Iyzipay\Model\BasketItem();
$secondBasketItem->setId("BI102");
$secondBasketItem->setName("Game code");
$secondBasketItem->setCategory1("Game");
$secondBasketItem->setCategory2("Online Game Items");
$secondBasketItem->setItemType(\Iyzipay\Model\BasketItemType::VIRTUAL);
$secondBasketItem->setPrice("0.5");
$basketItems[1] = $secondBasketItem;
$thirdBasketItem = new \Iyzipay\Model\BasketItem();
$thirdBasketItem->setId("BI103");
$thirdBasketItem->setName("Usb");
$thirdBasketItem->setCategory1("Electronics");
$thirdBasketItem->setCategory2("Usb / Cable");
$thirdBasketItem->setItemType(\Iyzipay\Model\BasketItemType::PHYSICAL);
$thirdBasketItem->setPrice("0.2");
$basketItems[2] = $thirdBasketItem;
$request->setBasketItems($basketItems);

$payment = \Iyzipay\Model\Payment::create($request, Config::options());