文章转自: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" %>
<!DOCTYPE html>
<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 = "1234@123.com";
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的最后一个}括号内包含一个全角的空格,很坑啊;


热搜词

eve定制主机建站高防无视ccsql server 2000 多少钱iphone发件服务器主机名绍兴无视cc服务器sql server 空间数据asp access空间cc服务端.mobi中文域名绍兴无视ccverisign 域名后缀空间怎么防CCcc域名的前景2016openvzvpscc香港pccw客服电话.cc是哪里的域名.love域名注册高防ecco超强cc攻击serverhold什么意思cc可以备案吗seo url structure 解释live域名可以备案么net域名与ccfdcservers 内容限制justhost和onevps香港pccw电讯盈科抗攻击服务器ftp sqlserver 命令行fivem高防服务器access压缩和修复数据库sqlserver主机名可登陆域名cc是什么意思access主机cc域名现在是怎么样香港 pccw dnsvesda深圳高防服务器不防ccsqlserver导入存储过程cc域名优惠码iphone6高防sql server产品免费co.cc域名ru域名 whois中文.mobi注册ru后缀是哪个国家weloveservers 8香港宽频网络 pccw香港pccw 服务器租用guru后缀域名simcentric 机房 pccwserver 2008 部署网站域名 reserved 能注册嘛域名状态 inactive高防苹果6怎么显示cmccramnode hostigationserver 2008 iis部署网站idcc公司server 2003 双网卡双线路godaddy mobi续费优惠码英文 mobi万网虚拟主机上传sqlserver数据库防ddos cc攻击空间kddi 服务器网站如何防止cc攻击服务器防御cc攻击cc攻击怎么防御卸载vestacpgeotrust 证书生成yonex高防品值多少钱云盾 防cckangle htaccess香港宽带pccw域名cc结尾cc英文名字sqlserver2005数据库access 30maruba 域名免费域名 ru高防gucci小蜜蜂cc攻击 规则网址cc域名怎么样游戏高防空间防cccc域名过期多久删除ddos cc攻击 购买windowsserver2003 分区cc英语可以注册吗sql server 云服务filezilla server添加用户cc已备案域名pccw 香港防cc攻击策略域名 inactive日本服务器kddi中国联通 pccwcc是哪个国家域名iphone 云服务器地址asp.net cc攻击mobi注传奇cc攻击器.cc注册价格