支付宝接入教程以及服务端给app写支付接口入门

发布时间:2018-06-26 20:26:33   来源:文档文库   
字号:

关于支付宝接入的几点说明和解释

在实际的开发中,我们看到开放平台密钥和合作伙伴密钥的时候,有没有直接就懵逼了的赶脚?反正我是的有。因为不是每个人都经常去开发支付功能,更不会有事儿没事儿去调这些个密钥,毕竟跟钱相关的东西,谁都会冷静三分!鉴于此,我简略说两点。

1.官方答复说,合作伙伴密钥适用于合作伙伴密钥常被适用于API 1.0版本的支付和移动支付手机网页支付),而开放平台密钥是作为APP支付设定的。经实际测试:合作伙伴密钥和开放平台密钥在移动支付(手机网页支付)和APP支付中都是没有问题的!

2.支付分为两种形式:一是demo接入方式(API 1.0的接入方式),一种是sdk调用API(此为API 2.0的接入方式)下面是分别对两种接入的解释说明:

1.demo接入方式(API 1.0的接入方式

中(官方答复)

1.0的支付api service为:$alipay_config['service'] = "alipay.wap.create.direct.pay.by.user";

服务端程序demo地址为: https://doc.open.alipay.com/doc2/detail?treeId=60&articleId=103564&docType=1

文档地址为:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.Wp8Ll3&treeId=60&articleId=104424&docType=1

打开demo当中的配置文件alipay.config.php能看到

Parenter 是合作身份PID。这个只要进行了支付宝签约就能看到,签约流程可以在https://b.alipay.com/中找到,不再进行说明。值得注意的是seller_id在官方的demo中可以看出seller_id partner,实际上seller_id 也可以是商家的支付宝账号。

从上面的配置中能看到私钥和支付宝公钥是直接写进去的。这有个要注意的地方,就是私钥和支付宝公钥必须一行存放,不能复制工具里面生成的文件中的beginend注释行。

当然此处也是可以写私钥和公钥的文件路径的,那么这个时候去掉注释和带着注释不影响总体结果,但是这个时候要注意的是支付宝的公钥必须是64个字符为一行,需要手动换行。建议大家用官方demo给的配置方式。直接复制私钥内容进行手动删除回车,直接复制支付宝公钥。(注意:支付宝的公钥需要换取的,也就是说用openssl工具生成的有两个密钥,一个是私钥,一个是公钥。这个公钥是要上传到合作伙伴密钥来换取支付宝公钥的。换言之,配置中的支付宝公钥是用生成的公钥换的。不是本身有的。)

生成的公钥自己手动删除回车然后点击“查看开发者公钥”进行设置修改。设置成功后,点击查看支付宝公钥,并且复制到配置中(如果要复制到文件中就要自己手动每64个字符一行进行回车换行)

一定要注意:公私钥是成对的,私钥存放本地,公钥要上传换取支付宝公钥!

2.SDK调用API(此为API 2.0的接入方式)

此时用到的密钥为开放平台密钥,官方答复说此为APP支付而设定。实际上并不是。(在第1条中有说明)

SDK的下载地址为:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.MG6YFx&treeId=54&articleId=103419&docType=1#s4

文档地址为:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.dNeARD&treeId=203&articleId=105285&docType=1#s3

手机支付API地址为:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.n5wlGc&treeId=203&articleId=105287&docType=1

首先看到sdk接入就要考虑到集成(请略过官方的集成说明)了。

先看官方文档中的前两条说明

准备工作做好,APP_ID(支付时候为基础应用的APPID ,公私钥(用工具再次生成一个,当然也可以用demo过程中生成的公钥私钥,然后用公钥上传到开放平台密钥的基础应用下面的查看应用公钥,进行换取此处的支付宝公钥)

集成的步骤是在你付款时候提交的actionphpinclude_once(SDK入口文件AopSdk.php);

接下来就是接收付款的form信息

具体写法看https://doc.open.alipay.com/doc2/detail.htm?treeId=203&articleId=105463&docType=1

中写法

示例中给的私钥和支付宝公钥都是文件存放的方式。(文件存放的格式说明请按照对demo中对文件中存放私钥和支付宝公钥的格式说明。)

此时需要注意的是

$aop = newAopClient ();

$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';

$aop->appId = 'your app_id';

$aop->rsaPrivateKeyFilePath = 'merchant_private_key_file';

$aop->alipayPublicKey='alipay_public_key_file';

$aop->apiVersion = '1.0';

$aop->postCharset='GBK';

$aop->format='json';

上面的参数也可以这么写

$aop = new AopClient();

$aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";

$aop->appId = APP_ID;

$aop->rsaPrivateKey = APP_PRIVATE_KEY;

$aop->format = "json";

$aop->charset= CHARSET;

$aop->alipayPublicKey = ALIPAY_PUBLIC_KEY;

标红地方的格式必须是这样类型的。对双引号进行转义。

如果有变量的话这样写:

此格式固定写法!!

有一点要说明,sdk传参是只要参入业务参数即可!

如果想修改returnUrl或者notifyUrl的时候直接$aop->returnUrl=正式的同步通知网址或者$aop->notifyUrl=正式的异步通知网址,两者选择一个即可!;

对参数的修改可以看AlipayTradeWapPayRequest类中的方法。

以上是对demosdk调试的基本用法,不尽或者有误的地方,大家可以测试雅正!、

下面讲讲如何给APP写支付接口!

服务端给客户端写接口须知:

1.要明确服务端要做的事情:私钥和支付宝公钥必须放在服务端,签名过程必须放在服务端。

2.在请求参数列表中,除去signsign_type两个参数外,其他需要使用到的参数皆是要签名的参数。

3.在同步通知、服务器异步通知参数列表中,除去signsign_type两个参数外,凡是通知返回回来的参数皆是要验签的参数。

4.sign值要做utf-8 URLencode

正式接入开始:

文档地址:https://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1

下载demo

移动支付的demo中有服务端demo代码(以php为例)

首先看服务器demo示例的配置文件alipay.config.php

好,我们此时看下请求参数文档会发现一个配置项是demo中缺少的!

请求参数文档地址:https://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103663&docType=1

我们对比配置文件,发现

也就说,demo的示例中少了seller_id这个必要参数!大家自己加上。seller_id的值是商家的支付宝账号!

在配置文件中,有两个参数需要注意private_keyalipay_public_key 这个应该是最近修正的写法。你会发现在之前的写法中是

也就是说,这个地方可以写公私钥的路径也可以写具体的公私钥内容,再次要注意的是:公私钥的格式!!用官方提供的openssl工具进行生成的私钥是保存到本地的,公钥用于上传并换取支付宝公钥,且存到本地,上传修改的位置是合作伙伴密钥(之前有讲过!!)如果曾经在网页上有支付宝支付,那么当时的私钥和支付宝公钥是可以再次使用的!无需修改!

配置项要说明的基本也就是这些,其他的都无需变动!

接下来就是服务端要集成demo的重头戏了,那就是生成签名操作

之前官方并没有给出明确的文档,说的也是相当模糊,写此文时候官方已经有文档解释。

附录文档地址:https://doc.open.alipay.com/doc2/detail.htm?treeId=59&articleId=103927&docType=1

看过它的文档还有些迷糊的话,请看如下我真实程序下的步骤过程:

在传递的接口文件中需要引入

写过接口的人都应该很清楚,只要给接口传递一个orderid就可以知道此订单的购物情况。那么接下来要进行的签名过程,和要给客户端发送的数据请严格按照下列代码进行!!

//先根据部分参数(订单信息)获取签名
$signParameter = array(
"partner" =>"\"".$alipay_config['partner']."\"",
"seller_id"=>"\"". $alipay_config['seller_id']."\"",
"out_trade_no" =>"\"".$orderArr['order_sn']."\"",
"subject"=>"\"".$orderArr['goods_name']."\"",
"body"=>"\"".$orderArr['goods_name']."\"",
"total_fee"=>"\"".$orderArr['pay_fee']."\"",
"notify_url"=>"\"".$alipay_config['notify_url']."\"",
"service" =>"\"". $alipay_config['service']."\"",
"payment_type" =>"\"". $alipay_config['payment_type']."\"",
"_input_charset" =>"\"".$alipay_config['input_charset']."\""
);
//获取预签名字符串
$strSign=createLinkstring($signParameter);
//调用RAS加密函数获取加密串
$result=rsaSign($strSign,$alipay_config['private_key_path']);
//将完整的信息发给客户端
$parameter = array(
"partner" =>"\"".$alipay_config['partner']."\"",
"seller_id"=>"\"". $alipay_config['seller_id']."\"",
"out_trade_no" =>"\"".$orderArr['order_sn']."\"",
"subject"=>"\"".$orderArr['goods_name']."\"",
"body"=>"\"".$orderArr['goods_name']."\"",
"total_fee"=>"\"".$orderArr['pay_fee']."\"",
"notify_url"=>"\"".$alipay_config['notify_url']."\"",
"service" =>"\"". $alipay_config['service']."\"",
"payment_type" =>"\"". $alipay_config['payment_type']."\"",
"_input_charset" =>"\"".$alipay_config['input_charset']."\"",
"sign"=>"\"".urlencode($result)."\"",
"sign_type"=>"\"".$alipay_config['sign_type']. "\""
);
$payinfo=createLinkstring($parameter);
exit('{"res":"1001","result":'.json_encode_ex($payinfo).'}');

看到exit里面的result会发现json_encode_ex这个函数,此函数为我自己为转换json_encode函数中文转码所写,实际上的写法是json_encode($payinfo)但是里面的中文全部被转换了。而支付宝的参数要求,明确要求,原码传递中文,文字是什么样的就是什么样的!

/* *

* 对变量进行 JSON 编码

* @param mixed value 待编码的 value ,除了resource 类型之外,可以为任何数据类型,该函数只能接受 UTF-8 编码的数据

* @return string 返回 value 值的 JSON 形式

*/

function json_encode_ex( $value)

{

if ( version_compare( PHP_VERSION,'5.4.0','<'))

{

$str = json_encode( $value);

$str = preg_replace_callback(

"#\\\u([0-9a-f]{4})#i",

function( $matchs)

{

return iconv('UCS-2BE', 'UTF-8', pack('H4', $matchs[1]));

},

$str

);

return $str;

}

else

{

return json_encode( $value, JSON_UNESCAPED_UNICODE);

}

}

上面说到了流程,下面稍微说一下对支付结果的处理:

支付的结果处理有两种方式:一个是同步通知,一个是异步通知(一定要明确自己用的是异步请求还是同步请求!Return_url是同步,notify_url是异步,选择其中之一!

我个人建议使用异步通知(习惯而已)

异步通知的url,无论是在APP支付还是网站支付中都形如notify_url,大家可以自己定位查询下,下面以为app写接口为例说明下notify_url

打开下载的服务端demo,我们会看到一个文件,notify_url.php,此文件就是异步通知的文件,异步通知回来后, 服务端就要根据异步的结果,去处理自己的程序逻辑,比如修改订单状态。

业务逻辑的处理,我见过有人写在0的位置,也有人写在1的位置,我个人是写在了1的位置。

当此时,一个完整的支付基本就写完了,关于支付的调试,其实支付宝是提供了 一个方法的。异步回来的结果是要再次进行验签的,基本上支付是否成功,就在验签的方法中得以体现,也就是说一些异步回来的信息,在验签的方法中是可以调试打印的!!

进到verifyNotify方法(如果用的是同步通知这个方法是verifyReturn())中我们可以看到

没错!!logResult就是支付宝提供的打印返回异步通知参数的方法(此方法写入的log.txt大家可以自己改路径)。通过这个你就很明显知道,订单到底成功还是没成功!

从上述的日志很容易就知道,客户端吊起支付之后出现的一些问题是怎么来的,哪里的问题!

好了,洋洋洒洒这么多,终于给一个完整的支付讲述完毕。实际开发中还需要大家多揣摩,多测试,多想多总结。

附录常见的问题错误总结(不尽之处大家自己总结积累)

A.demo来实现支付时出现的常见代码以及排查解决方法

注意:用手机网站支付demo或移动支付服务端demo调用的时候一般用的是合作伙伴密钥

ILLEGAL_SIGN获取签名时候拼装的参数有问题,检查顺序,对照文档必传项。

ALI38173 合作伙伴密钥或者开放平台密钥中上传的公钥,跟本地保存的私钥不是成对匹配的!重新生成公私钥,私钥存本地,公钥上传换取支付宝公钥!(一定要记住公私钥都要存在本地作为备份,包括换取的支付宝公钥要做备份!)

B.SDK调用API来实现支付时出现的常见代码以及排查解决方法

错误代码 invalid-signature 错误原因: 无效签名

上述的方法包裹json的时候必须是双引号

错误代码 missing-signature 错误原因: 缺少签名参数

私钥和公钥不成对匹配

LI38173 1.业务参数不全 2.开放平台密钥中上传的公钥,跟本地保存的私钥不是成对匹配的!重新生成公私钥,私钥存本地,公钥上传换取支付宝公钥

本文来源:https://www.2haoxitong.net/k/doc/adfc9b1303020740be1e650e52ea551810a6c9a0.html

《支付宝接入教程以及服务端给app写支付接口入门.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式