QuikWallet Partner Integration

QuikWallet is a PCI-DSS Level-1 certified payment gateway, developed by LivQuik Technology (India) Pvt. Ltd. that enables users to transact with credit card, debit card, net banking and various other payment modes. Merchants can also host closed-loop prepaid cards on the QuikWallet platform and use QuikWallet as a secure card vault.

Entities Involved

  • QuikServer - The QuikWallet server which is identified by a URL; which for our UAT server is https://uat.quikpay.in/api/
  • YourServer - Your server which is identified by:>
  • Partner ID - Provided by QuikWallet to identify you as a partner
  • Secret key - Provided by QuikWallet and which should be securely stored on your server and never shared with the end user.
  • YourApplication - Your web / smart phone application using which your users will carry out payments, recharges & store cards. This will be identified by:
  • Partner ID
  • Users 10 digit mobile number
  • Signature - You will generate the signature using the secret key provided to you, the users 10 digit mobile number and HMAC-SHA256 as shown here http://www.freeformatter.com/hmac-generator.html. Signature = HMAC-SHA256 (users mobile number, secret key)

Before We Begin

  1. This document will use our UAT endpoints for development and testing. On completion of the same, we will give you details of the production environment.Our UAT server's DNS is https://uat.quikpay.in
  2. All API calls will have this much in common https://uat.quikpay.in/api/
  3. All requests are to use HTTP POST method.
  4. All API exchange (request and response) is in JSON format. The request object varies from API endpoint to endpoint, but all responses are 200 OK (even the failed ones). All responses have a key success (which is either success or failed), and can optionally have message or data. message, whenever present will usually be a human readable string which can be displayed in your UI. Occasionally, message or data or both could be null.

Success Example :

{
"status":"success",
"data":
   {
       "can" : "be",
       "any" : "object",
       "or": "array",
       "based" : "on",
       "the" : "context"
   },
"message" : "some message here"
 }

Failed Example :

{
"status":"failed",
"data":
   {
      "can" : "be",
      "any" : "object",
      "or": "array",
      "based" : "on",
      "the" : "context"
   },
"message":"What went wrong."
 }

While integrating, you will be dealing with two types of APIs:

a.Server-to-Server APIs b. Client-to-Server APIs

a.Server-to-Server APIs

  1. These are APIs called directly from YourServer to the QuikServer.
  2. All Server-to-Server calls will need to include your partner ID and the secret key in the request.
  3. You will be assigned different partner IDs for both UAT and production by us which will be used in all Server-to-Server API calls as part of the request.
  4. For example, if your partner id is 42, you will structure the URL as https://uat.quikpay.in/api/partner/42/...

b. Client-to-Server APIs

  1. These are APIs called from YourApplication to the QuikServer.
  2. All Client-to-Server calls will need to include your partner ID, users 10 digit mobile number and signature in the request. The signature, like mentioned above, is generated using a combination of the users mobile number & the Secret Key provided by us & using HMAC-SHA256. For HMAC-SHA256 implementation, refer http://www.freeformatter.com/hmac-generator.html. Signature = HMAC SHA256(10 digit mobile number, secret key)
  3. For Client-to-Server calls we will assume you have authenticated the user & their mobile number at your end.
  4. The request URL will be structured as https://uat.quikpay.in/api/user/...

Note:

  1. Partnerid and Secret Key will be assigned by QuikWallet and must be configurable in your server.
  2. Secret Key is critical to security and should be stored only on your servers and not transmitted in any form to the end user.
  3. For security purposes, server to server IP white listing might be required.
  4. All requests & responses will use strings.

Section A: Using QuikWallet as a Card Vault

This section describes how to use QuikWallet as a secure PCI-compliant card vault. The API calls are of the Client-to-Server type, so as to keep your server out of PCI scope.

  1. Adding a card to our vault POST https://uat.quikpay.in/api/user/addcard

Request example:

{
  "mobile":"6432949000",   
  "signature":"82335083d7fa9dc3dab475b66fb07f55d41fea15a8bd719246be7d0c8c86dadd","partnerid":"1",
   "ccno":"5123456789012346",
   "expmm":"03",
   "expyyyy":"2015",
   "name":"Pinay Vinto"
}

In this request, all fields are mandatory. The keys are as follows:

  1. Mobile is the users registered (we recommend verified) mobile number (without the '+91'prefix).
  2. Signature is the signature generated using the users mobile number & the Secret Key provided by QuikWallet.
  3. Partnerid is your partner id provided by QuikWallet.
  4. ccno is the credit card number. We have an enforced check of minimum length of 15 digits. We recommend you check this using Luhn Algorithm.
  5. Expmm is the expiry month in MM format. We have an enforced check of minimum length of 2 digits.
  6. Expyyyy is the expiry year in YYYY format. We have an enforced check of minimum length of 4 digits.
  7. Name is the name of the user as on the card.

*Note: As per regulations, one cannot store the CVV code.***

Successful Response Example:

{
"status":"success",
    "data":{
    "type":"CREDIT",
    "cardid":"3340",
    "network":"mastercard",
    "tail":"2346",
    "bank":"BANCO DEL PICHINCHA, C.A."
},
"message":"Card successfully added"
}

For a successful response we are sending back the following information which you can display in your UI:

  1. Type - Whether payment card type is credit or debit.
  2. Cardid - id generated by us for the card which you can store at your end
  3. Network - the network the card belongs to i.e. Visa, MasterCard, Amex
  4. Tail - the last four digits of the card
  5. Bank - the issuing bank for the card Note: With regard to type & bank information, while we try to provide the correct information, this information tends to be imprecise at this stage and can only be confirmed after a payment has been made using that card.

Failed Response Example:

{
"status": "failed",
"message": "Invalid card number",
}

2.Listing all cards in the vault POST https://uat.quikpay.in/api/user/cards

Request example:

{
"mobile":"6432949000",
"signature":"82335083d7fa9dc3dab475b66fb07f55d41fea15a8bd719246be7d0c8c86dadd",
"partnerid":"1"
}

Successful Response Example:

{
"status":"success",
"data":{
   "paymentcards":[
   {
    "type":"CREDIT",
    "cardid":"3340",
    "network":"MASTERCARD",
    "tail":"2346",
    "bank":"BANCO DEL PICHINCHA, C.A."
 },
 {
    "type":"DEBIT",
    "cardid":"3341",
    "network":"VISA",
    "tail":"2346",
    "bank":""
  }
  ],
    "prepaidcards":[
  {
    "prepaidid":"9999",
    "balance":"100"
  }
  ]
  },
"message":null
}

The response will consist of an array for paymentcards i.e. debit & credit cards saved by the user with QuikWallet and an array of prepaid cards saved by the user. For a prepaid card,only the prepaid card id (prepaidid) and the balance on the card will be returned.

3.Deleting a card from the vault POST https://uat.quikpay.in/api/user/deletecard

Request Example

{
"mobile":"6432949000",
"signature":"82335083d7fa9dc3dab475b66fb07f55d41fea15a8bd719246be7d0c8c86dadd",
"partnerid":"1",
"cardid":"3431"
}

Successful Response Example

{
"status":"success",
"message":"Card successfully deleted"
}

Section B: Recharging a Prepaid Card

POST https://uat.quikpay.in/api/user/recharge

Users can recharge their prepaid card stored with QuikWallet using various payment methods such as payment cards saved in their QuikWallet card vault, non-saved payment cards & net banking

The request will change depending on the payment method the user uses to recharge the prepaid card.

Request example - saved payment card

{
  "mobile":"6432949000",
  "signature":"82335083d7fa9dc3dab475b66fb07f55d41fea15a8bd719246be7d0c8c86dadd",
  "partnerid":"1",
  "email":"vinay.pinto@livquik.com",
  "prepaidid":"9999",
  "amount":"100",
  "cardid":"3340",
  "cvv":"234",
  "paymentmode":"paymentcard"
}

Request example - non-saved payment card

{
   "mobile":"6432949000",
   "signature":"82335083d7fa9dc3dab475b66fb07f55d41fea15a8bd719246be7d0c8c86dadd",
   "partnerid":"1",
   "email":"vinay.pinto@livquik.com",
   "prepaidid":"9999","amount":"100",
   "ccno":"5123456789012346",
   "expmm":"03",
   "expyyyy":"2015",
   "name":"Pinay Vinto",
   "cvv":"234" ,
   "paymentmode":"paymentcard"
}

Request example - net banking

{
   "mobile":"6432949000",
   "signature":"82335083d7fa9dc3dab475b66fb07f55d41fea15a8bd719246be7d0c8c86dadd",
   "partnerid":"1",
   "email":"vinay.pinto@livquik.com",
   "prepaidid":"9999",
   "amount":"100",
   "netbankingcode":"HDFB",
   "paymentmode":"netbanking"
}

Note: List of net banking codes (netbankingcode) will be provided separately.

In all the above cases, the successful response will be the same.

Successful Response Example

{
  "status":"success",
  "data":{
  "id":"R‐23444",
  "url":"https://uat.quikpay.in/2fr/req/2eg3hd2"
  } 
}

From this response, you have to display the link in url field in a webview for the user to enter the 3D secure password & complete the payment

  1. Once the user successfully completes the 3DSecure entry , the URL in the webview will change to https://uat.quikpay.in/2fr/success (for success) andhttps://uat.quikpay.in/2fr/failed (for failure). It is possible to monitor this change and close the webview when this happens, taking control back to your application with a success/failure message for the user depending on which URL was eventually opened. At the end of this document, example code for how to detect this URL change in Android and iOS is given (Appendix A & Appendix B respectively).

  2. Also, when the user completes the 3D Secure flow, we will call a URL from your server (which you register with us ) and post details of the transaction there to 'notify' your server in real time. Suppose you register the callback URL as: http://www.yourserver.com/callback Then, at the point of completion of 3DSecure, we will post JSON data to this URL.

Example POST you will receive

{
  "type":"recharge",
  "data":{
  "partnerid":"4",
  "amount":"100",
  "id":"R‐21436",
  "state":"paid",
  "mobile":"9819638168"
  }
}

Section C: Conducting a Payment

StackEdit stores your documents in your browser, which means all your documents are automatically saved locally and are accessible offline!

For conducting a payment, we will be using the direct debit flow, where the amount to be paid is debited from the users prepaid card. POST https://uat.quikpay.in/api/partner/partnerid/requestpayment

Request Example

{
 "partnerid":"<partner_id>",
 "outletid":"<outlet_id_associated_with_the_partner>",
 "mobile":"<customer_mobile_no>",
 "secret":"<partner_secret_key>",
 "amount":"<amount_to_be_sent>",
 "orderid":"<bill_number_of_request>"
}

Successful Response Example

{
  "status": "success",
  "data": {
  "id": "P-214335",
  "link": "https://uat.quikpay.in/#paymentrequest/Oywm9tF"
  {
}

Appendix A

webView.setWebViewClient(new WebViewClient() {
   public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}  
//For monitoring changes to URL :
public void onPageFinished(WebView view, String url) {
    if (progressBar.isShowing())
        progressBar.dismiss();
Intent twoFactorResultIntent = new Intent();
if (url.contains("2fr/failed")) {
    // Handle failure here
} else if (url.contains("2fr/success")) {
// Handle success here }
}

public void onReceivedError(WebView view, int errorCode,
     String description, String failingUrl) {
//Handle error
});

webView.loadUrl("https://uat.quikpay.in/2fr/req/" + id);

Appendix B


   (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)
    request navigationType:(UIWebViewNavigationType)navigationType
    {
    if(navigationType == UIWebViewNavigationTypeonTypeFormSubmitted)
    {
    NSString *stringUrl = [request.URL absoluteString];
    block NSMutableDictionary *prepaidCards = nil;
    if([stringUrl rangeOfString:@"#2fr/success"].location!=NSNotFound)
    {
    // show payment successful
    }
    else if([stringUrl rangeOfString:@"#2fr/failed"].location!=NSNotFound)
    {
    // show failure view
    }
    }
    return YES
    }


That's it for now. For any queries contact yudhajit.nag@livquik.com