因公司业务须要,须要给客户接入支付宝支付,本身之前只作过网页版支付宝支付。折腾了3天,踩了不少坑,终于搞定了,如今记录一下,分享给你们.
1、首先必须通知客户先申请支付宝商家帐号,而后认证。固然这是废话...没有帐号还支付个毛线...
而后让客户登录支付宝帐号后,右上角有个开放平台,点开.php
点开以后是这个样子.前端
这里都是须要客户操做的,客户点击支付接入后,会有个认证签约页面,签约完以后,会生成应用惟一标识(APPID)。应用建立完成后,系统会自动跳转到应用详情页面。而后能够点击 添加功能 来添加App支付功能。添加功能完后,个人应用列表就会显示添加的应用,即支付宝App支付。由于个人是我的号,因此无法演示。这一部咱们只须要等待客户申请就好,什么也不用作。详细流程参加支付宝官方文档:https://docs.open.alipay.com/... 这里面惟一须要开发者作的就是生成密钥这一步。express
点击红线部分快速签名教程就能够跳转到签名工具页面,json
点击下载,我是windows环境,下载完成后,打开工具。我是php开发,因此选非JAVA适用,点击生成密钥就会出现两大坨,一个是商户私钥一个是商户公钥(就是开发者私钥公钥).而后右下角有个上传公钥按钮,点击会跳转到支付宝开放平台页面。windows
由于我不是商家,没法认证,因此这是空白的。若是是商家帐号,就会显示相似于这个页面:api
点击RSA设置,填上 开发者公钥私钥,就会生成一个新的支付宝公钥。到此一步,申请的部分完成。数组
下面是开发者后台接入的部分:服务器
在开始后台代码前,咱们必须有3个参数,开发者私钥、支付宝公钥、APPID。 这里的开发者私钥也叫应用私钥,一个意思,不要绕晕了。
没有这3个参数,就无法唤起支付宝支付接口!!!
准备好后能够下载支付宝的官方demo代码参考。demo在这个页面下载:https://docs.open.alipay.com/...
打开是酱紫:微信
我本身用TP5封装了一个方法,童鞋能够参考下:app
<?php
namespace appapicontroller;
use appcommoncontrollerRootsApi;
use thinkDb;
require_once EXTEND_PATH . '/alipay/AopSdk.php';
/**
*/
class Alipay extends RootsApi
{
//应用APPID,都是2019开头
const APPID = '2019*';
//开发者私钥去头去尾去回车,一行字符串
const RSA_PRIVATE_KEY = '';
//支付宝公钥(上传开发者公钥(又叫应用公钥)后才能生成)
const ALIPAY_RSA_PUBLIC_KEY = '';
public function _initialize()
{
parent::_initialize();
}
/**
*支付方法,调用支付宝接口成功后,会返回给前端一个长串的参数字符串。前端利用它唤起支付宝
*/
public function paytoOffi()
{
try { //调支付宝接口(这里写死测试,实际按逻辑来) $res = $this->getAlipayMsg('买单','消费者买单',2342424214234,0.01); return json_encode($res);//必须是json格式 } catch (\Exception $e) { return false; }
}
/**
*/
public function notify()
{
$arr = $_POST;
file_put_contents('d.txt',json_encode($arr),FILE_APPEND);//写入txt支付宝的返回数据
//验证签名
$aop = new AopClient();
$aop->alipayrsaPublicKey = self::ALIPAY_RSA_PUBLIC_KEY;
$flag = $aop->rsaCheckV1($arr, null, "RSA2");
if ($flag) {
//验签 //处理业务,并从$arr中提取须要的参数内容 if ($arr['trade_status'] == 'TRADE_SUCCESS' || $arr['trade_status'] == 'TRADE_FINISHED') { //处理交易完成或者支付成功的通知 //本身的业务逻辑,好比修改订单为已支付 die('success'); //必须有这句,echo 'success'也能够,不然支付宝会觉得支付没成功,而在一天内连续调用异步接口,容易出错 }
}
}
/**
*/
private function getAlipayMsg($body, $subject, $out_trade_no, $amount)
{
$aop = new \AopClient(); $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";//这里是写死的,支付宝网关地址 $aop->appId = self::APPID; $aop->rsaPrivateKey = self::RSA_PRIVATE_KEY; $aop->format = "json"; $aop->charset = "UTF-8"; $aop->signType = "RSA2"; $aop->alipayrsaPublicKey = self::ALIPAY_RSA_PUBLIC_KEY; //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay $request = new \AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只须要传入业务参数 $bizcontent = "{\"body\":\"{$body}\","//支付商品描述 . "\"subject\":\"{$subject}\","//支付商品的标题 . "\"out_trade_no\":\"{$out_trade_no}\","//商户网站惟一订单号 . "\"timeout_express\":\"60m\","//该笔订单容许的最晚付款时间,逾期将关闭交易 . "\"total_amount\":\"{$amount}\","//订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] . "\"product_code\":\"QUICK_MSECURITY_PAY\"" . "}"; $request->setNotifyUrl('http:xxxxx.com/api/alipay/notify');//你本身的异步地址,必须写全,并且不能有参数 $request->setBizContent($bizcontent); //这里和普通的接口调用不一样,使用的是sdkExecute $response = $aop->sdkExecute($request); $result = array('order_str'=> $response); return $result;
}
}
首先前台调支付接口paytoOffi,而后这个方法就会调getAlipayMsg方法,即调支付宝接口的方法,这4个参数描述、标题、订单号、价格后3个是必填的。描述能够不填,这个酌情修改。而后调接口,支付宝会返回请求字符串,即唤起支付宝软件的一长串字符串,这里有个大坑,官方文档上说直接echo 给前台就行,但其实应该转成json格式返给前台,不然会报100XX错误,即参数格式不正确。下面是官方的坑教程截图:
每次看见这句不须要再作处理我就来气...当时坑了我两天,就是没想起来要转JSON格式返回。我这里是把返回的字符串放进一个数组,而后再json_encode返回。返回的字符串若是在页面上打印是这个样子的
我没有截全,很长一大串。(前端要去掉order_str的键名,取键值)
前端拿着这串东西就能够唤起支付宝软件,进行支付,支付成功后,你写的支付宝异步回调函数就会收到一串信息,notify方法的$_POST就有数据了。能够转成JSON格式打印出来:
{
"gmt_create": "2019-06-24 17:16:03", "charset": "UTF-8", "seller_email": "********", "subject": "\u4e70\u5355", "sign": "***********", "body": "\u6d88\u8d39\u8005\u4e70\u5355", "buyer_id": "*******", "invoice_amount": "0.01", "notify_id": "**********", "fund_bill_list": "*********", "notify_type": "trade_status_sync", "trade_status": "TRADE_SUCCESS",//交易状态,success为支付成功 "receipt_amount": "0.01", "app_id": "*******", "buyer_pay_amount": "0.01", "sign_type": "RSA2", "seller_id": "", "gmt_payment": "2019-06-24 17:16:03", "notify_time": "2019-06-24 17:19:10", "version": "1.0", "out_trade_no": "1624677580792188",//你本身的订单号 "total_amount": "0.01",//支付总金额 "trade_no": "************",//支付宝流水号 "auth_app_id":"***********", "buyer_logon_id": "",//买家的支付宝帐号 "point_amount": "0.00"
}
星号部分都是有值的。
只要trade_status的值是success就是支付成功
取出里面的订单号 价格之类的就能够写业务逻辑了,具体看https://docs.open.alipay.com/... 参数说明。最后别忘了在异步方法返回一个"SUCCESS",不然支付宝会觉得没支付成功,24小时内每一个10几分钟就调一次异步接口。
至此,整个支付流程就走完了,支付宝虽然有点坑,可是比微信支付强多了,微信的文档才是真的坑!欢迎童鞋们参考。