123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <?php
- /**
- * @note: 支付宝 APP支付、手机网站支付、当面付
- * @author: jdzor <895947580@qq.com>
- * @date: 2019/3/14
- */
- namespace payment\alipay;
- /**
- * 统一支付
- * 接口文档:https://docs.open.alipay.com/
- * 公共错误码:https://docs.open.alipay.com/common/105806
- * 说明:
- * 1.当面付不用设置应用网关和授权回调地址,只需要设置应用公钥
- *
- * 使用方法:
- * 1.当面付
- * $alipay = new Alipay($config);
- * $info = $alipay->placeQrcode($payData);
- * $info['code'] != 10000 && json_error((($info['sub_msg'] ?? '') . ' ' . $info['sub_code'] ?? ''), -2);
- * $info['code_url'] 通过qrcode生成二维码后,用户扫码即可
- * 2.app支付
- * $alipay = new Alipay($config);
- * $info = $alipay->placeApp($payData);
- * 将结果$info传给移动端即可,$info是将参数http_build_query()处理后生成的字符串
- * 3.手机网站支付
- * $alipay = new Alipay($config);
- * $info = $alipay->placeWap($payData);
- * $info['html_form'] 将结果通过ajax方式写入html body中即可
- * 4.电脑网站支付
- * $alipay = new Alipay($config);
- * $info = $alipay->placePage($payData);
- * $info['html_form'] 将结果通过ajax方式写入html body中即可
- *
- * Class AlipayQrcode
- * @package app\common\extend\alipay
- */
- class Alipay extends BaseAlipay
- {
- const PRECREATE_URL = 'alipay.trade.precreate'; //当面付 扫码
- const APP_PAY_URL = 'alipay.trade.app.pay'; //App支付
- const WAP_PAY_URL = 'alipay.trade.wap.pay'; //手机网站支付
- const PAGE_PAY_URL = 'alipay.trade.page.pay'; //电脑网站支付
- const CLOSE_URL = 'alipay.trade.close'; //关闭订单
- const QUERY_RUL = 'alipay.trade.query'; //查询订单
- public function __construct($config)
- {
- parent::__construct($config);
- }
- //下单参数检测
- private function check($param)
- {
- isset($param['order_no']) || json_error('缺少参数:order_no');
- isset($param['order_price']) || json_error('缺少参数:order_price');
- isset($param['subject']) || json_error('缺少参数:subject');
- isset($param['notify_url']) || json_error('缺少参数:notify_url');
- $this->notifyUrl = $param['notify_url'];
- isset($param['return_url']) && $this->returnUrl = $param['return_url'];;
- }
- //下订单 当面付
- public function placeQrcode($param)
- {
- $this->check($param);
- isset($param['expire']) || json_error('缺少参数:expire');
- //请求参数
- $requestConfig = [
- 'out_trade_no' => $param['order_no'], //商户订单号
- 'total_amount' => $param['order_price'], //订单总金额,整形,此处单位为元,精确到小数点后2位,不能超过1亿元
- 'subject' => $param['subject'], //订单标题,粗略描述用户的支付目的
- 'qr_code_timeout_express' => floor($param['expire'] / 60) . 'm', //当面付 二维码过期时间
- 'timeout_express' => $this->timeoutExpress //交易创建后才生效
- ];
- $result = json_decode($this->commonRequest($requestConfig, self::PRECREATE_URL), true);
- return $result['alipay_trade_precreate_response'];
- }
- //下订单 APP支付
- public function placeApp($param)
- {
- $this->check($param);
- //请求参数
- $requestConfig = [
- 'out_trade_no' => $param['order_no'], //商户订单号
- 'total_amount' => $param['order_price'], //订单总金额,整形,此处单位为元,精确到小数点后2位,不能超过1亿元
- 'subject' => $param['subject'], //订单标题,粗略描述用户的支付目的
- 'timeout_express' => $this->timeoutExpress //交易创建后才生效
- ];
- $result = $this->commonRequest($requestConfig, self::APP_PAY_URL);
- return ['alipay' => $result];
- }
- //下订单 手机网站支付
- public function placeWap($param)
- {
- $this->check($param);
- //请求参数
- $requestConfig = [
- 'out_trade_no' => $param['order_no'], //商户订单号
- 'total_amount' => $param['order_price'], //订单总金额,整形,此处单位为元,精确到小数点后2位,不能超过1亿元
- 'subject' => $param['subject'], //订单标题,粗略描述用户的支付目的
- 'timeout_express' => $this->timeoutExpress, //交易创建后才生效
- 'product_code' => 'QUICK_WAP_WAY', //销售产品码,商家和支付宝签约的产品码,如:QUICK_WAP_WAY
- ];
- $result = $this->commonRequest($requestConfig, self::WAP_PAY_URL);
- return $this->buildRequestForm($result);
- }
- //下订单 电脑网站支付
- public function placePage($param)
- {
- $this->check($param);
- //请求参数
- $requestConfig = [
- 'out_trade_no' => $param['order_no'], //商户订单号
- 'total_amount' => $param['order_price'], //订单总金额,整形,此处单位为元,精确到小数点后2位,不能超过1亿元
- 'subject' => $param['subject'], //订单标题,粗略描述用户的支付目的
- 'timeout_express' => $this->timeoutExpress, //交易创建后才生效
- 'product_code' => 'FAST_INSTANT_TRADE_PAY', //销售产品码,商家和支付宝签约的产品码,注:目前仅支持 FAST_INSTANT_TRADE_PAY
- ];
- $result = $this->commonRequest($requestConfig, self::PAGE_PAY_URL);
- return $this->buildRequestForm($result);
- }
- /**
- * 建立请求,以表单HTML形式构造(默认)
- * @param array $param 请求参数数组
- * @return array 提交表单HTML文本
- */
- private function buildRequestForm($param)
- {
- $html = "<form id='alipaysubmit' name='alipaysubmit' action='" . self::GATEWAY_URL
- . "?charset=" . $this->charset . "' method='POST'>";
- foreach ($param as $key => $val) {
- if (false === $this->checkEmpty($val)) {
- $val = str_replace("'", "'", $val);
- $html .= "<input type='hidden' name='" . $key . "' value='" . $val . "'/>";
- }
- }
- //submit按钮控件请不要含有name属性
- $html = $html . "<input type='submit' value='ok' style='display:none;'></form>";
- $html = $html . "<script>document.forms['alipaysubmit'].submit();</script>";
- return ['html_form' => $html];
- }
- /**
- * 查询订单
- * 文档:https://openclub.alipay.com/read.php?tid=5407&fid=72
- * 当面付:生成二维码使用支付宝钱包扫码唤起收银台后订单创建,支付宝未扫码前查询显示交易不存在 ACQ.TRADE_NOT_EXIST
- * 支付宝钱包支付(手机网站):用户点击支付,唤起支付宝收银台后,输入正确完整的支付密码后订单创建
- * 支付宝钱包支付(APP支付):用户点击支付,唤起支付宝收银台后,输入正确完整的支付密码后订单创建
- * @param $outTradeNo
- * @return mixed
- */
- public function queryOrder($outTradeNo)
- {
- //请求参数
- $requestConfig = array(
- 'out_trade_no' => $outTradeNo //订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 trade_no,out_trade_no 如果同时存在优先取trade_no
- );
- $result = json_decode($this->commonRequest($requestConfig, self::QUERY_RUL), true);
- return $result['alipay_trade_query_response'];
- }
- /**
- * 关闭订单
- * 文档:https://openclub.alipay.com/read.php?tid=5407&fid=72
- * 当面付:生成二维码使用支付宝钱包扫码唤起收银台后订单创建,支付宝未扫码前查询显示交易不存在 ACQ.TRADE_NOT_EXIST
- * 支付宝钱包支付(手机网站):用户点击支付,唤起支付宝收银台后,输入正确完整的支付密码后订单创建
- * 支付宝钱包支付(APP支付):用户点击支付,唤起支付宝收银台后,输入正确完整的支付密码后订单创建
- * @param $outTradeNo
- * @return mixed
- */
- public function closeOrder($outTradeNo)
- {
- //请求参数
- $requestConfig = array(
- 'out_trade_no' => $outTradeNo //订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 trade_no,out_trade_no 如果同时存在优先取trade_no
- );
- $result = json_decode($this->commonRequest($requestConfig, self::CLOSE_URL), true);
- return $result['alipay_trade_close_response'];
- }
- //异步通知 验签
- public function rsaCheck($param)
- {
- return parent::rsaCheck($param);
- }
- /**
- *程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。
- * 一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h)
- */
- public function replyNotify()
- {
- echo 'success';
- }
- }
|