Make on demand payments using a vaulted card

Tokenization and Vaulting

Step 1: Setup your Maya Business Manager Account

Before you could integrate Maya Card Payment Vault to your websites, you must register and setup your Maya Business Manager Account.

Step 2: Build your pages

Get the card details

Create a form that would accept the card details from the customer

Sample code:
<html>
  <head>
    <title>Save card</title>
  </head>
  <body>
    <form action="/tokenize-customer-card" method="POST">
      <input class="cn" placeholder="Card number">
      <input class="date" placeholder="MM / YY">
      <input class="cvc" placeholder="CVC" type="password">
      <button type="submit">Link a card</button>
    </form>
  </body>
</html>

️Is your platform PCI-DSS Certified?

Do not store any card information (i.e. name, card number, expiry dates, cvv/cvc) on your application unless your platform is PCI-DSS certified.

Get the Customer details

Create a form that would accept the required customer information when making card payments.

{
  "id": "d29f1635-8313-4ed4-94e5-94b6a6018f52",
  "firstName": "Maya",
  "middleName": "Jose",
  "lastName": "Juan",
  "contact": {
    "phone": "+63(2)1234567890",
    "email": "[email protected]"
  },
  "billingAddress": {
    "line1": "6F Launchpad",
    "line2": "Sheridan Street",
    "city": "Mandaluyong City",
    "state": "Metro Manila",
    "zipCode": "1552",
    "countryCode": "PH"
  },
  "shippingAddress": {
    "firstName": "Maya",
    "middleName": "Jose",
    "lastName": "Juan",
    "line1": "6F Launchpad",
    "line2": "Sheridan Street",
    "city": "Mandaluyong City",
    "state": "Metro Manila",
    "zipCode": "1552",
    "countryCode": "PH",
    "phone": "+63(2)1234567890",
    "email": "[email protected]",
    "shippingType": "ST"
  },
  "sex": "F",
  "birthday": "1987-07-28",
  "customerSince": "2020-12-25",
  "createdAt": "2021-07-06T14:01:25.000Z",
  "updatedAt": "2021-07-06T14:01:25.000Z"
}
Step 3: Submit details for tokenization

Tokenize the card details


Once customer have provided their card details, your system must send these information to /payments/v1/payment-tokens endpoint and obtain the paymentTokenId.


Sample code:
  const createPaymentTokenUrl = 'https://pg-sandbox.paymaya.com/payments/v1/payment-tokens';
	const options = {
  	headers: {
    	'Content-Type': 'application/json',
    	'Authorization': `Basic ${btoa('SECRET_KEY')}`
  	},
		method: 'POST',
		body: cardData
	};

	const paymentTokenId = await fetch(createPaymentTokenUrl, options)
  	.then(res => res.json())
  	.then(json => {
   		return json.paymentTokenId
  	})
  	.catch(err => console.error('error:' + err));

Submit customer details


Submit the customer details to Maya vault and obtain the unique customer ID via the /payments/v1/customers endpoint.


ℹ️ Maya recommends that you keep the Id of the customer record from the response. This Id can be used to retrieve customer details and card tokens.

Sample code:
  const createCustomerUrl = 'https://pg-sandbox.paymaya.com/payments/v1/customers';
	const options = {
  	headers: {
    	'Content-Type': 'application/json',
    	'Authorization': `Basic ${btoa('SECRET_KEY')}`
  	},
		method: 'POST',
		body: customerData
	};

	const customerIdFromMayaVault = await fetch(createCustomerUrl, options)
  	.then(res => res.json())
  	.then(json => {
      // Your code to keep the customerId on your application
   		return json.id
  	})
  	.catch(err => console.error('error:' + err));
Step 4: Link paymentTokenId to the customer

At this point, you will have two (2) variables available - customerId and paymentTokenId. Send these variables to /payments/v1/customers/{customerIdFromMayaVault}/cards endpoint to link them together.

ℹ️ paymentTokenId can only be linked once. Attempts after successful link will reject the request.


Sample code:
  const createCustomerCardUrl = 'https://pg-sandbox.paymaya.com/payments/v1/customers/${customerIdFromMayaVault}/cards';
  	const options = {
  		headers: {
    		'Content-Type': 'application/json',
    		'Authorization': `Basic ${btoa('SECRET_KEY')}`
  		},
			method: 'POST',
			body: {
     		paymentTokenId,
     		redirectUrl: {
    			success: 'http://localhost:8080/success',
    			failure: 'http://localhost:8080/failure',
    			cancel: 'http://localhost:8080/cancel',
  			}
    	}
		};

	fetch(createCustomerCardUrl, options)
  	.then(res => res.json())
  	.then(cards => {
        // Assuming first entry in cards list has VERIFIED state
        const cardTokenId = cards[0].cardTokenId      
   		response.redirect(303, json.verificationUrl)
  	})
  	.catch(err => console.error('error:' + err));

ℹ️ You can also save the cardTokenId for future use, but be aware that a customer can have multiple cards and may have set their default cards. To retrieve and validate the customer’s cards, call the GET /payments/v1/customers/{customerId}/cards endpoint.

You will notice that linking of customer to their credit card will return 2 items: cardTokenId and verificationUrl. Your application should redirect to the verificationUrl in order to trigger user authentication which will depend on the issuing bank's 3DS authentication.

Verification

There are 2 flows to verifying the linked card: through test charge of Php 10.00 or through payment of their current transaction.

  1. Through Test Charge
  2. From the successful call of the POST, your application should be redirected to the verificationUrl from the response data to continue the verification process.

    Sample spiel for the Test Charge

    📨 We will be charging Php 10 to the customer's card. This amount will be automatically refunded back.

  3. Through payment of current transaction
  4. Initiate the payment of the current customer transaction through POST. This will give you a new verificationUrl that your application should redirect to.

🧪 Quick Test

  1. Input card details using one of our test cards.
  2. Click the Link a card button.
  3. You are redirected to Issuing Bank's verification page.
  4. On successful verification, your customer will be redirected to the success page.

Retrieve Cards of the Customer

Use this endpoint to retrieve and validate the cards of a customer.

These fields would help you identify which is the default usable card of the customer:

state (string)Indicates the state of the card being attached to the customer:
PREVERIFICATION : 3DS verification is required to add the card to the customer.
VERIFIED : card is successfully added to the customer.
EXPIRED : an attempt to add the card to the customer has expired.
defaultIndicates if the card is the default card of the customer.

ℹ️ If you are looking for the default usable card, you must get the cardTokenId with state = VERIFIED and default = true.

Making Payments

Step 1: Execute on-demand payments

Use the acquired cardToken and customer ID from Maya Vault to execute payments anytime.

ℹ️ For this integration, Maya Card Payment Vault serves as a secure card storage only. Scheduling and triggering of payments will be done by your system.

Sample code:
async app.post('/customers/:customerId/cards/:cardToken/execute-payment-from-customer-card', async (request, response) => {
  const url = `https://pg-sandbox.paymaya.com/payments/v1/customers/{request.params.customerId}/cards/{request.params.cardToken}/payments`;
  const options = {
    method: 'POST',
    headers: {accept: 'application/json', 'content-type': 'application/json'},
    body: request.body
  };

  const response = await fetch(url, options)
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error('error:' + err));
})
Step 2: Handle post-payment events

The redirection after a successful payment does not guarantee that the payment information will be updated. Your application should manage payment information updates by implementing webhooks.

Useful Links