Alipay Miniprogram
Prerequisites
- 2C2P shall create MiniProgram on AlipayMiniProgram Portal and setup keys
- 2C2P shall invite Merchant's developer to the mini program development
- Merchant shall be able to develop miniprogram
- 2C2P shall provide StoreID for the merchant
- Merchant to host the merchant backend api to make API call to 2C2P to make payments
Payment Flow
Integration Guide
Below show sample codes and explanation of each functions.
Environment
Please refer Demo & Live Endpoint.
For Front End Implementation
- Prepare JS function to call backend server
JS Function | Description |
---|---|
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);
}
}
Updated almost 3 years ago