These docs are for v3.2.6. Click to read the latest docs for v4.3.0.

Alipay Miniprogram

Prerequisites

  1. 2C2P shall create MiniProgram on AlipayMiniProgram Portal and setup keys
  2. 2C2P shall invite Merchant's developer to the mini program development
  3. Merchant shall be able to develop miniprogram
  4. 2C2P shall provide StoreID for the merchant
  5. Merchant to host the merchant backend api to make API call to 2C2P to make payments

Payment Flow

1201

 

Integration Guide


Below show sample codes and explanation of each functions.

🚧

Environment

Please refer Demo & Live Endpoint.

 
For Front End Implementation

  1. Prepare JS function to call backend server
JS FunctionDescription
GetUserToken()Call to merchant backend server to process retrieve user token via 2c2p
GetTradeNo()Call to merchant backend server to process securepay payment.
<script>
    function GetUserToken() {
        var code = $("#authcode").val();
        var jqxhr = $.ajax({
            url: 'api/usertoken',
            type: 'POST',
            data: { 'authCode': code },
            dataType: 'json',
            success: function (d) {
                $("#userid").text('UserId: ' + d.userId);
                $("#alipay_user_id").val(d.userId);
                $("#getTradeNo").removeAttr('disabled');
            },
            error: function (d) {
                console.log(d);
                alert("error");
            }
        })
    };

    function GetTradeNo() {
        var code = $("#alipay_user_id").val();
        var jqxhr = $.ajax({
            url: 'api/payment',
            type: 'POST',
            data: { 'userId': code },
            dataType: 'json',
            success: function (d) {
                $("#tradeNo").text('tradeNo: ' + d.tradeNO);
            },
            error: function (d) {
                console.log(d);
                alert("error");
            }
        })
    };
</script>
<body>
    <input type="text" id="authcode" />
    <input type="button" onclick="GetUserToken()" value="GetUserToken" />
    <span id="userid"></span>
    <br />
    <input type="text" id="alipay_user_id" name="alipay_auth_code" maxlength="64" placeholder="Alipay User ID"  />
    <input type="button" id="getTradeNo" onclick="GetTradeNo()" value="GetTradeNo" />
    <span id="tradeNo"></span>
</body>

 
For Back End Implementation

1. Get User Token
Following show the the backend code that how to retrieve userToken via 2c2p using API function. This API function should called from front end.

[HttpPost]
public IHttpActionResult usertoken(string authCode)
{
  UserTokenData data = new UserTokenData();

  // RETRIEVE merchantId, merchantSecretKey from your database
  string merchantId = "JT01";            //Get MerchantID from 2c2p PGW Dashboard
  string merchantSecretKey = "7jYcp4FxFdf0";      //Get SecretKey from 2c2p PGW Dashboard

  var tokenRequest = new UserTokenRequestPayload()
  {
    AuthCode = authCode,
    Version = "1.0",
    MerchantID = merchantId,
    PaymentChannel = "ALMINI"
    };

  var createJWTResponse = Utility.CreateJWT(tokenRequest, merchantSecretKey);
  if (createJWTResponse.Result)
  {
    string requestData = createJWTResponse.ResultOutput;
    var payloadBody = new PayloadBody() { Payload = requestData };
    var userTokenResponse = Utility.PostRequest("https://demo2.2c2p.com/miniprogram/1.0/UserToken/retrieve", JsonConvert.SerializeObject(payloadBody));
    if(userTokenResponse.Result)
    {
      var payloadData = JsonConvert.DeserializeObject<PayloadBody>(userTokenResponse.ResultOutput);
      var verifyJWTResponse = Utility.VerifyJWT(payloadData.Payload, merchantSecretKey);
      if(verifyJWTResponse.Result)
      {
        var tokenResponse = JsonConvert.DeserializeObject<UserTokenResponsePayload>(verifyJWTResponse.ResultOutput);
        if (tokenResponse.ResponseCode == "6100")
        {
          data.userId = tokenResponse.UserToken;
          return Ok<UserTokenData>(data);
        }
        else
        {
          return BadRequest(tokenResponse.ResponseDescription);
        }

      }
    }
  }
  return BadRequest();
}

 
2. Make Payment via SecurePay API
Following show the the backend code that how to prepare & make payment via SecurePay API. This API function should called from front end.

📘

Secure Pay API

Refer Refer Payload Parameter Specification & API Parameter Specification

[HttpPost]
public IHttpActionResult Post([FromBody]PaymentData paymentData)
{
  string paymentChannel = "", userId = "", storeId = "", storeName = "", storeTerminalId = "";

  //Merchant Account Information
  string merchantID = "JT01";    //Get MerchantID from 2c2p PGW Dashboard
  string secretKey = "7jYcp4FxFdf0";     //Get SecretKey from 2c2p PGW Dashboard

  //Product Information
  string uniqueTransactionCode = "Invoice" + DateTime.Now.ToString("yyMMddHHmmss");
  string desc = "item 1";
  string amt = "000000000001";            //12 digit format
  string currencyCode = "702";            //Ref: http://en.wikipedia.org/wiki/ISO_4217

  //Customer Information
  string cardholderName = "John Doe";
  string country = "SG";

  //Payment Channel
  paymentChannel = "ALMINI"; // Alipay H5 App
  userId = paymentData.userId; // user_id
  storeId = paymentData.storeId; // alipay provided
  storeName = "123 Store";
  storeTerminalId = "ST0001"; // alipay provided

  //Request Information
  string timeStamp = DateTime.Now.ToString("ddMMyyHHmmss");
  string apiVersion = "9.9";


  //Construct payment request message
  string payloadXml = "<PaymentRequest>" +
    "<timeStamp>" + timeStamp + "</timeStamp>" +
    "<merchantID>" + merchantID + "</merchantID>" +
    "<uniqueTransactionCode>" + uniqueTransactionCode + "</uniqueTransactionCode>" +
    "<desc>" + HttpUtility.HtmlEncode(desc) + "</desc>" +
    "<amt>" + amt + "</amt>" +
    "<currencyCode>" + currencyCode + "</currencyCode>" +
    "<panCountry>" + country + "</panCountry>" +
    "<cardholderName>" + cardholderName + "</cardholderName>" +
    "<paymentChannel>" + paymentChannel + "</paymentChannel>" +
    "<miniProgramData>" +
    "<alipay>" +
    "<userID>" + userId + "</userID>" +
    "<storeID>" + storeId + "</storeID>" +
    "<storeName>" + HttpUtility.HtmlEncode(storeName) + "</storeName>" +
    "<storeTerminalID>" + storeTerminalId + "</storeTerminalID>" +
    "</alipay>" +
    "</miniProgramData>" +
    "</PaymentRequest>";



  string payload = Utility.Base64Encode(payloadXml);                                //Convert payload to base64  
  string hash = Utility.GetHMAC2(payload, secretKey);                         //Calculate Hash Value


  string xml = "<PaymentRequest>" +
    "<version>" + apiVersion + "</version>" +                                          //request version number (9.9)
    "<payload>" + payload + "</payload>" +                                             //request payload
    "<signature>" + hash + "</signature>" +                                       //signature
    "</PaymentRequest>";

  string data = Utility.Base64Encode(xml);                                //Convert payload to base64          
  data = "paymentRequest=" + HttpUtility.UrlEncode(data);        //urlEncode data

  string url = "https://demo2.2c2p.com/2C2PFrontEnd/SecurePayment/Payment.aspx"; //securepay payemnt url

  var paymentResponse = Utility.PostRequest(url, data, Utility.PostContentType.FORM);
  if (paymentResponse.Result)
  {
    if (!string.IsNullOrEmpty(paymentResponse.ResultOutput))
    {
      string clearResult = Utility.Base64Decode(paymentResponse.ResultOutput);
      XmlDocument xDoc = new XmlDocument();
      xDoc.LoadXml(clearResult);
      string respPayload = (xDoc.SelectNodes("//payload").Count > 0 ? xDoc.SelectSingleNode("//payload").InnerText : "");
      string respSign = (xDoc.SelectNodes("//signature").Count > 0 ? xDoc.SelectSingleNode("//signature").InnerText : "");

      string respHash = Utility.GetHMAC2(respPayload, secretKey);                         //Calculate Hash Value


      respPayload = Utility.Base64Decode(respPayload);
      if (respHash.Equals(respSign, StringComparison.OrdinalIgnoreCase))
      {
        XmlDocument xDocResponse = new XmlDocument();
        xDocResponse.LoadXml(respPayload);
        string respCode = (xDocResponse.SelectNodes("//respCode").Count > 0 ? xDocResponse.SelectSingleNode("//respCode").InnerText : "");
        if (respCode == "32")
        {
          string alipayData = (xDocResponse.SelectNodes("//miniProgramData//alipay").Count > 0 ? xDocResponse.SelectSingleNode("//miniProgramData//alipay").InnerText : "");
          return Json(alipayData);
        }
        else
        {
          return BadRequest("Failed to get tradeNo");
        }

      }
      else
      {
        return BadRequest();
      }
    }
    else
    {
      return BadRequest("Empty response");
    }
  }
  else
  {
    return BadRequest(paymentResponse.ErrorDetails);
  }

}