前一久做了支付宝支付,分享一下接入的详细步骤吧,移动端和服务端demo源码移步至文章末尾。
先给出支付宝官方文档:https://docs.open.alipay.com/204/105051/

适用场景

在App内集成支付宝支付。APP调用支付宝提供的SDK,SDK再调用支付宝APP内的支付模块。如果用户已安装支付宝APP,商家APP会跳转到支付宝中完成支付,支付完后跳回到商家APP内。如果用户没有安装支付宝APP,商家APP内会调起支付宝网页支付收银台,用户登录支付宝账户,支付完后展示支付结果。

接入
1. 创建应用并获取APPID

地址:https://open.alipay.com/platform/appManage.htm#/apps

创建应用后即生成应用的标识APPID
创建指南:https://docs.open.alipay.com/200/105310/

2. 添加App支付功能

从我的应用列表点击应用对应的查看详情按钮进入

添加完成后,若应用状态为开发中状态,只能在沙箱环境下进行调试。应用申请上线后,会同时申请此列表的功能,接口即生效。

注:手机端支付可以添加 APP支付 和手机网站支付。APP支付使用原生开发,调用支付宝支付SDK。手机网站支付是在网页中调用支付宝,所以使用h5+mui方式开发APP可使用此功能,无需跳转至原生。这里根据需要酌情选择。

3. 签约

在功能列表中点击签约,签约后才能正常使用,签约前可使用沙箱模式进行调试。

以上的步骤可以交给公司相关人员进行申请,开发人员请看下面


密钥配置
1. 支付宝密钥处理体系

所以需要获取到应用公钥、应用私钥以及支付宝公钥:

应用公钥
由商户自己生成的RSA公钥(与应用私钥必须匹配),商户需上传应用公钥到支付宝开放平台,以便支付宝使用该公钥验证该交易是否是商户发起的。

应用私钥
由商户自己生成的RSA私钥(与应用公钥必须匹配),商户开发者使用应用私钥对请求字符串进行加签。

支付宝公钥
支付宝的RSA公钥,商户使用该公钥验证该结果是否是支付宝返回的。

2. 获取密钥和密钥配置

步骤:https://docs.open.alipay.com/200/105310#s2
签名专区:https://docs.open.alipay.com/291/106103/
密钥生成工具:https://docs.open.alipay.com/291/106097/

注:使用密钥生成工具生成密钥时,要注意密钥格式,如果服务端使用.Net或其他非java语言,一定要选PKCS1(非JAVA适用),否则后面要凉凉。密钥长度建议选择2048。

集成开发

使用App支付功能需要在原生中实现,这里以Android为例。接入移动支付需要集成两个SDK,分别是客户端的SDK和服务端的SDK。

SDK下载地址:
客户端https://docs.open.alipay.com/54/104509
服务端https://docs.open.alipay.com/54/106370/

注:为何需要两个SDK?因为客户端不能含有敏感信息,包括密钥、APPID等,这些东西都必须从服务端获取,包括加签验签过程,所以还需要集成一个服务端给APP调用。

客户端(Android)SDK集成

集成方法:https://docs.open.alipay.com/204/105296/

(1)发起支付请求

支付宝SDK中提供了一个PayTask类,使用其payV2方法即可发起支付请求。

/**
* 支付(加签过程不允许在客户端进行,必须在服务端,否则有极大的安全隐患)
*
* @param orderInfo 加签后的支付请求参数字符串(主要包含商户的订单信息,key=value形式,以&连接)。
*/
private void pay(final String orderInfo) {final Runnable payRunnable = new Runnable() {@Overridepublic void run() {PayTask alipay = new PayTask(MainActivity.this);//第二个参数设置为true,将会在调用pay接口的时候直接唤起一个loadingMap<String, String> result = alipay.payV2(orderInfo, true);Message msg = new Message();msg.what = SDK_PAY_FLAG;msg.obj = result;mHandler.sendMessage(msg);}};// 必须异步调用Thread payThread = new Thread(payRunnable);payThread.start();
}

参数:
orderInfo: app支付请求参数字符串,主要包含商户的订单信息,key=value形式,以&连接。由众多请求参数加签以及非对称加密后生成。
具体参数说明请看文档:https://docs.open.alipay.com/204/105465/

所以发起支付请求的重点在于获取orderInfo,也就是从服务端获取加签结果,加签过程不允许在客户端进行,否则可能被反编译,造成严重的后果。所以加签过程请看下面服务端(.Net)SDK集成的第(1)条。

(2)支付回调

调用支付宝支付后,将会收到同步通知和异步通知。如果过程中取消支付则只会收到同步通知。

同步通知:支付宝sdk对商户的请求支付数据处理完成后,会将结果同步反馈给app端。在支付回调中即可获取支付结果信息。
异步通知: 对于App支付产生的交易,支付宝会根据原始支付API中传入的异步通知地址notify_url,通过POST请求的形式将支付结果作为参数通知到商户系统。

注: 手机端同步通知有可能存在获取不到的情况,如手机关机,应用crash等情况,所以手机端同步回调只作为支付结果提示。真正的支付成功逻辑将在支付宝异步通知(服务端)中做处理,请看下面服务端(.Net)SDK集成的第(2)条。

so,手机端只做同步通知处理,如下:

Map<String, String> result = alipay.payV2(orderInfo, true);

result就是返回的同步回调结果,里面的resultStatus是支付状态码,如果是9000则支付成功。

if (TextUtils.equals(resultStatus, "9000")) {// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。showAlert(MainActivity.this, "支付成功" + payResult);} else {// 该笔订单真实的支付结果,需要依赖服务端的异步通知。showAlert(MainActivity.this, "支付失败" + payResult);}

如果使用混合开发(h5+mui+原生),还需跳转至mui页面,则可使用js回调函数将同步通知传入mui端进行后续处理,如:

// 调用方法将原生代码的执行结果返回给js层并触发相应的JS层回调函数
JSUtil.execCallback(mWebview, CallBackID, resultStatus, JSUtil.OK, false);
服务端(.Net)SDK集成

集成方法:https://docs.open.alipay.com/54/106370/

为了便于支付宝异步接口调用,这里服务端将使用webApi,服务端主要工作为加签、验签(异步通知验证)以及更改订单支付状态。

(1) 加签

核心步骤:

//从pem文件中读取
APP_PRIVATE_KEY = GetCurrentPathByAbs() + "rsa_private_key.pem";
ALIPAY_PUBLIC_KEY = GetCurrentPathByAbs() + "rsa_alipay_public_key.pem";//最后一个参数为false直接将私钥内容写入代码,true从pem文件中读取
IAopClient client = new DefaultAopClient(gateway, APPID, APP_PRIVATE_KEY, format, version, sign_type, ALIPAY_PUBLIC_KEY, CHARSET, true);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称如:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.Body = body;
model.Subject = subject;
model.TotalAmount = total_amount;
model.ProductCode = product_code;
model.OutTradeNo = out_trade_no;
model.TimeoutExpress = timeout_express;
request.SetBizModel(model);
request.SetNotifyUrl(notify_url);
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = client.SdkExecute(request);string resp = response.Body;
return resp;

支付宝服务端SDK中提供了一个SdkExcute方法,需要传入对应的request类AlipayTradeAppPayRequest。实例化IAopClient对象时需要传入请求网关(gateway)、APPID、应用私钥、支付宝公钥、调用的接口版本、编码方式、签名算法类型以及是否从文件中读取密钥的一个bool类型值。
其中,签名算法类型应和配置密钥时选择的类型一致,另外2018年1月5号之后创建的应用都需要使用RSA2,也就是sign_type=RSA2,否则会加签失败。最后一个bool型参数,为false直接从代码中读取密钥,为true则从pem文件中读取。

如果觉得密钥放在代码中不够安全的话,建议将密钥存储为pem文件,执行加签过程时从文件中读出,做法如下:

① 生成pem文件

pem文件是有格式的,就像这样

-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAjayyr4gU38hr/EYnXdbEfbaGkdVnvf6Y+9zWkkiPcNq-----这里是密钥内容
-----END RSA PRIVATE KEY-----

生成pem文件需要使用openssl.exe这个可执行文件,当然也可以copy个pem文件替换下里面的密钥内容,不过这样有可能会导致格式乱了。openssl.exe在密钥生成工具的openssl的bin目录下,双击即可打开。

生成应用私钥pem文件,输入命令:genrsa -out rsa_private_key.pem 2048


生成应用公钥pem文件,输入命令:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem


支付宝公钥需要上传应用公钥获取,如果不使用pem文件,代码中直接放上支付宝公钥就行,如果要使用pem文件,可以将应用公钥的pem文件复制一份,将密钥内容换成支付宝公钥的,格式如下。

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAADCBi----------这里是支付宝公钥
-----END PUBLIC KEY-----

注:上面密钥的格式默认为PKCS1的,如果使用PKCS8(Java适用)别忘记执行转码命令,否则也要凉凉的。如果使用沙箱模式请将密钥换成沙箱版进行测试。

② 从pem文件中读取密钥

首先获取存放密钥文件的路径,为了防止出现意外,可获取文件的绝对路径,如下:

/// <summary>
/// 获取私钥公钥的路径(绝对路径)
/// </summary>
/// <returns></returns>
private static string GetCurrentPathByAbs()
{return HttpRuntime.AppDomainAppPath.ToString() + "rsa/";
}

获取到文件路径后传入IAopClient的构造函数中,并将最后一个参数置为true即可。

IAopClient client = new DefaultAopClient(gateway, APPID, APP_PRIVATE_KEY, format, version, sign_type, ALIPAY_PUBLIC_KEY, CHARSET, true);
(2) 验签

当支付宝发送异步通知时,会将支付结果的信息异步返回至服务端,服务端需要进行验签操作,验证请求是否是支付宝发送,并利用支付宝公钥进行比对,保证交易的安全性和正确性。主要步骤如下:
①提供异步调用接口
支付宝异步通知将以post的方式发起请求,所以我们需要编写一个webapi接口,并保证接口的正确性,如下:

/// <summary>
/// 异步验签(客户端支付后,支付宝服务器将异步调用此方法)
/// 实际支付逻辑在此操作,支付宝服务端将保证调用到此接口
/// </summary>
/// <returns></returns>
[HttpPost]
public string GetAsynchronousYanQian()
{return AlipayUtil.AsynchronousYanQian(GetRequestPost());
}

这个接口地址便是加签过程中传入的异步通知地址notify_url

②获取异步通知结果并验签
官方文档地址:https://docs.open.alipay.com/54/106370/

上面这个链接支付宝介绍了如何获取通知参数并验签。但是部分代码是错的,请看我写的。
获取支付宝异步通知结果如下:

/// <summary>
/// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组
/// request回来的信息组成的数组
/// </summary>
/// <returns></returns>
public Dictionary<string, string> GetRequestPost()
{int i = 0;IDictionary<string, string> sArray = new Dictionary<string, string>();NameValueCollection coll;coll = Request.Form;String[] requestItem = coll.AllKeys;for (i = 0; i < requestItem.Length; i++){sArray.Add(requestItem[i], Request.Form[requestItem[i]]);}return (Dictionary<string, string>)sArray;
}

验签:
验签过程支付宝AlipaySignature类提供了验签方法RSACheckV1和RSACheckV2,区别就不细说,这里使用RSACheckV1方法,第一个参数便是支付宝返回的异步通知结果,第二个参数传入支付宝公钥,同样最后一个参数传false从代码读取支付宝公钥,传true从pem 文件中读取。

bool flag = AlipaySignature.RSACheckV1(result, ALIPAY_PUBLIC_KEY, CHARSET, sign_type, true);

验签结果返回一个bool值,如果验签成功返回true,否则false。

③通知支付宝
支付宝异步通知调用接口后,如果未收到成功反馈,将会在一段时间内重复发送异步通知,以保证服务端接收到异步通知。所以当验签成功并真正的改变订单支付状态后,需要给支付宝返回success。如果反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h)。

if (flag)
{//验签成功,将数据库中订单的支付状态改变if (ChangePayState()){//如果数据库插入成功,通知支付宝已收到通知return "success";}else{return "fail";}}
else
{return "fail";
}

注:如果在改变订单支付状态时需要的某些参数无法获取,可以将其拼接在加签过程中某些不是很必要的参数里,支付宝将在异步通知中返回。

效果图


以上便是支付宝支付的实现步骤,包括了移动端(原生)和服务端(.Net)。Demo已上传至GitHub,有兴趣的可以下载:

移动端:https://download.csdn.net/download/xch_yang/85594997
服务端:https://download.csdn.net/download/xch_yang/85595041

原创不易,转载请注明:https://blog.csdn.net/xch_yang/article/details/86689642

手把手教你接入支付宝支付相关推荐

  1. Android 接入支付宝支付实现

    接上篇android接入微信支付文章,这篇我们带你来接入支付宝支付服务 简介 首先要说明的是个人感觉接入支付宝比微信简单多了,很轻松的,所以同学们不要紧张~ 当然还是老规矩啦,上来肯定的贴上官网地址, ...

  2. Android接入支付宝支付实现

    接上篇android接入微信支付文章,这篇我们带你来接入支付宝支付服务 简介 首先要说明的是个人感觉接入支付宝比微信简单多了,很轻松的,所以同学们不要紧张~ 当然还是老规矩啦,上来肯定的贴上官网地址, ...

  3. 腾腾流氓,云云更流氓(问微信怎样接入支付宝支付),手贱的赶紧点,你会感谢我的...

    草原上的两匹马! 打从当年微信开始布局公众号之初时,估计就已经想到了与支付宝正面冲突的场面,所以微信先来个瞒天过海,在春晚搞了个微信红包,那叫一个火呀,此时的云云隐隐感觉到些许不安. 早期的微信开发者 ...

  4. 2021-02-11-JavaWeb网站接入支付宝支付

    JavaWeb网站接入支付宝支付 前言 前序步骤 接入 pom.xml 在沙箱环境获取测试账号,以及付钱的账号 公钥私钥的生成可以下面这个工具 Controller层 模拟付款 前言 今天给大家分享一 ...

  5. iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手

    iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手 前言 发现iOS支付宝逆向的分析并不多,蚂蚁森林基于H5应用 套着UIWebView 基本也没这类JS和原生交互分析的帖子,就拿此练手吧 作技术分享 ...

  6. 网站接入支付宝支付之扫码支付

    接入支付宝支付需要在支付宝开发平台创建应用获取appid,创建后需要审核,所以我们用支付宝提提供的沙箱环境开发测试. 首先登录支付宝开放平台,在开发者中心选择研发服务->沙箱环境->沙箱应 ...

  7. PHP 支付PC端扫码支付、APP接口调起支付宝支付、微信公众号接入支付宝支付

    第一:第三方支付原理 第二:支付接口申请流程 地址:https://docs.open.alipay.com/270/105899/ : 参考地址:https://blog.csdn.net/nove ...

  8. iphone快捷指令蚂蚁森林能量_iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手...

    iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手 前言 发现iOS支付宝逆向的分析并不多,蚂蚁森林基于H5应用 套着UIWebView 基本也没这类JS和原生交互分析的帖子,就拿此练手吧 作技术分享 ...

  9. Java接入支付宝支付测试买iPhone13 pro max

    Java接入支付宝支付 一.介绍 二.沙箱 三.支付流程 四.准备支付宝 五.代码 1.前端代码 2.后端代码 六.测试 一.介绍 支付宝官方网站 支付宝(中国)网络技术有限公司是国内的第三方支付平台 ...

  10. SpringBoot 接入支付宝支付-证书模式

    SpringBoot 接入支付宝支付-证书模式 满足一下条件 1.注册支付宝商户,实名认证,获取APPID 2.申请支付宝公钥证书 3.有些复杂具体还是按照官方引导进行操作 产品大全 https:// ...

最新文章

  1. sql sever avg保留小数_《数据库系统概念》笔记 (一)SQL
  2. 实用网站和在线工具推荐
  3. 「压缩」会是机器学习的下一个杀手级应用吗?
  4. linux信号处理编程实验报告,Linux编程之信号处理
  5. vscode中设置.mina语法高亮
  6. Google获得MapReduce专利
  7. 压缩、解压 解决 客户端查询大批量数据时等待时间过长的问题
  8. Android 性能优化工具
  9. python和java学哪个好-Python和Java该学哪个?还在纠结的你看过来呀~
  10. python实现网站测速软件_python实现网站友情链接查询与网站死链接查询的两个脚步...
  11. php vld扩展,Linux安装php-vld扩展
  12. 纪录黑马程序员的真实生活
  13. java 基础复习
  14. CM311-1a linux游戏服务器操作立马拥有我的世界私人服务器哦
  15. wps建立的文件后缀名为docx,写在里面的东西还不允许保存
  16. 【草莓音乐节】现场美女大放送
  17. Raspberry Pi3驱动Oled ssh1106屏
  18. Python基础--魔法方法()运算符重载)
  19. GEE开发之Modis_NPP数据分析和获取
  20. 测试环境部署——selenium+python

热门文章

  1. 计算机组成原理运算器设计实验之8位可控加减法电路设计
  2. c语言转换字符类型,C语言基础之数据类型转换
  3. [Pytorch系列-24]:神经网络基础 - 单个无激活函数的神经元实现简单线性回归 - 1
  4. 毛咕咕 百度有啊现在每天的成交量:
  5. 360随身wifi,不通过360wifi软件,直接运行网卡模式
  6. 【Unity】射击小游戏
  7. 强大的Pidgin,Pidgin的使用
  8. Android进程管理详解
  9. 蓝牙协议栈HCI EIR(EXTENDED INQUIRY RESPONSE)扩展搜索响应
  10. 时间漩涡的世界 (一)