文章转自:https://zuoluo11.github.io/2017/07/04/%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7%E9%9B%86%E5%90%88%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98/ 感谢本作者
API及业务逻辑
手机网站支付API可以前往以下网址查看及下载sdk:
目前手机网站支付demo有: JAVA和PHP版本
SDK则有:JAVA、.NET和PHP版本
手机支付API
SDK下载
微信公众号集成帮助包
签名sign生成规则
代码实现
###普通手机网站用户进行确认下单页面
namespace AliPayDemo
{
public partial
class Pay : System.Web.UI.Page
{
//不是真实数据
string APPID =
"2017090907474487";
//应用ID
//应用私钥
string APP_PRIVATE_KEY = @
"****JEwKBgQCIFY+12QuI3gI478vsixJiYOWJb2T7MRr0Zlg2n3fnQWnVB2gOkSgls/CHM3y+d/GQRJRE5aFWa2Xt";
//支付宝公钥
string ALIPAY_PUBLIC_KEY = @
"***PXZOf8eQx+qWGky6LJZWie4IF2oqY7El1nps2qVg1IbQkDdIMNSr2a2nQF5GwSpVcF7bRZeNG2qgs3EjHu4hGqXMWbg6Fvs1iigiBYfkzQIDAQAB";
string CHARSET =
"utf-8";
//编码格式
protected void Page_Load(object sender, EventArgs e)
{
//SDK已经封装掉了公共参数,只需要初始化一次
IAopClient client =
new DefaultAopClient(
"https://openapi.alipay.com/gateway.do", APPID, APP_PRIVATE_KEY,
"json",
"1.0",
"RSA2", ALIPAY_PUBLIC_KEY, CHARSET,
false);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称如:alipay.trade.wap.pay.request
AlipayTradeWapPayRequest request =
new AlipayTradeWapPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
//此次只是参数展示,未进行字符串转义,实际情况下请转义
//注意value类型,如金额没有引号,
request.BizContent =
"{" +
" \"subject\":\"大乐透\"," +
" \"out_trade_no\":\"70501111111S0011111191\"," +
" \"total_amount\":0.01," +
" \"product_code\":\"QUICK_WAP_WAY\"" +
" }";
AlipayTradeWapPayResponse response = client.pageExecute(request);
divBody.InnerHtml = response.Body;
////调用成功,则处理业务逻辑
//if (response.IsError)
//{
// //.....
//}
}
}
}
|
###微信公众号内用户进行确认下单页面
1、下载集成微信公众号的帮助包并将文件放入项目文件夹中
ap.js 跳转到自带浏览器js
pay.htm 提示用户跳转htm页面
1、使用pageExecute方法,以GET方式获得url字符串;这个就得到了拼接好的支付url返回前台a标签里面就可以了
1
2
|
AlipayTradeWapPayResponse response = client.pageExecute(request,null,"GET");
test = response.Body;
|
2、将Url传入前台页面标签,待用户点击确定
1
|
<a id="test" href="<%=test%>" class="button button-big button-fill">支付宝结算
</a>
|
3、用户点击页面后跳转到提示页,提示用户使用手机自带浏览器打开连接
4、完成支付
5、整体的代码
前端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="JsApiPayPage1.aspx.cs" Inherits="JsApiPayPage1" %>
<html>
<head runat="server">
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>微信支付
</title>
</head>
<body style="background-color: #efeff4;">
<form runat="server" id="calculator" v-cloak>
<div class="content-block">
<a id="test" href="<%=test%>" class="button">支付宝结算
</a>
</div>
</form>
</body>
</html>
<script>
//绑定单击事件
var btn =
document.querySelector(
"#test");
btn.addEventListener(
"click",
function (e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
//ele.href 是GET到支付宝收银台的URL
_AP.pay(e.target.href);
return
false;
},
false);
</script>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
using System;
using System.Collections.Generic;
using CYQ.Data;
using Web.Lianmengban_2016;
using CYQ.Data.Table;
using Aop.Api.Util;
using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
public partial
class JsApiPayPage1 : System.Web.UI.Page
{
public
static
string test { get;
set; }
protected void Page_Load(object sender, EventArgs e)
{
CreateAliPayPramaters();
}
private void CreateAliPayPramaters()
{
//pageExecute<T>(IAopRequest<T> request, string accessToken, string reqMethod) where T : AopResponse
IAopClient client =
new DefaultAopClient(
"https://openapi.alipay.com/gateway.do", AliConfig.APP_ID, AliConfig.APP_PRIVATE_KEY,
"json",
"1.0",
"RSA2", AliConfig.ALIPAY_PUBLIC_KEY, AliConfig.CHARSET,
false);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称如:alipay.open.public.template.message.industry.modify
AlipayTradeWapPayRequest request =
new AlipayTradeWapPayRequest();
//AlipayOpenPublicTemplateMessageIndustryModifyRequest request = new AlipayOpenPublicTemplateMessageIndustryModifyRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
//此次只是参数展示,未进行字符串转义,实际情况下请转义
request.BizContent =
"{" +
" \"subject\":\"大乐透\"," +
" \"out_trade_no\":\"70501111111S0011111191\"," +
" \"total_amount\":0.01," +
" \"product_code\":\"QUICK_WAP_WAY\"" +
" }";
AlipayTradeWapPayResponse response = client.pageExecute(request,null,
"GET");
test = response.Body;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
class AliConfig
{
//=======【基本信息设置】=====================================
/* 支付宝手机网页支付信息配置
public const string URL = "https://openapi.alipay.com/gateway.do";
public const string APP_ID = "20170111111144";
public const string APP_PRIVATE_KEY = @"MIIEowIBAAKCAQEA31kawX3d***t";
public const string FORMAT = "json";
public const string CHARSET = "utf-8";
public const string ALIPAY_PUBLIC_KEY = @"MIIBIjANBgkqhkiG9***";
public const string SIGN_TYPE = "RSA2";
public const string SELLER_EMAIL = "[email protected]";
public const string NOTIFY_URL = "http://www.222.net/ResultNotifyAliPay.aspx";
public const string RETURN_URL = "http://www.222.net/AliReturnPage.aspx";
}
|
总结及出现的问题
1、参数的内容
按照api提供的列表把必填项的key及value一定要写全,写对;
2、BizContent的业务参数内多个参数之间用“,”号隔开,之前忘记写全,报错;
3、签名错误
sign_valid
API里面生成签名,包括sign_type
接收支付宝的异步通知时,验签之前不包括sign 和 sign_type
签名sign生成规则
支付宝官方sdk有个bug,Aop.Api.Util.AlipaySignature类中方法没有去掉sign_type就进行验证,导致出错;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public static bool RSACheckV2(IDictionary<string, string> parameters, string publicKeyPem)
{
string sign = parameters[
"sign"];
parameters.Remove(
"sign");
parameters.Remove(
"sign_type");
//新增修改bug
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, DEFAULT_CHARSET,
"RSA");
}
public static bool RSACheckV2(IDictionary<string, string> parameters, string publicKeyPem, string charset)
{
string sign = parameters[
"sign"];
parameters.Remove(
"sign");
parameters.Remove(
"sign_type");
//新增修改bug
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, charset,
"RSA");
}
public static bool RSACheckV2(IDictionary<string, string> parameters, string publicKeyPem, string charset, string signType, bool keyFromFile)
{
string sign = parameters[
"sign"];
parameters.Remove(
"sign");
parameters.Remove(
"sign_type");
//新增修改bug
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, charset, signType, keyFromFile);
}
|
4、交易订单处理失败 请稍后再试 ali38173
转到支付宝时,弹出这个错误,找了很久,才发现是由于Bizcontent的最后一个}括号内包含一个全角的空格,很坑啊;