支付宝当面付与h5支付
配置文件
路径:config/payment.php
没有就手动创建一个
<?php
return [
'wechat' => '',
'alipay' => [
'app_id' => '2021xxxx71', //APPID
'method' => 'alipay.trade.wap.pay', //相当于标识了你的支付方式如:手机网站支付就用alipay.trade.wap.pay
'charset' => 'UTF-8', //编码格式
'sign_type' => 'RSA2', //签名方式
'version' => '1.0', //版本统一都是1.0
'timestamp' => date('Y-m-d H:i:s'), //时间戳
'format' => 'json', //传输数据格式
//私钥
'prikey' => '这里放私钥内容',
]
];
控制器
<?php
namespace app\api\controller;
use support\Request;
//支付宝支付
class AlipayController {
//h5支付
public function h5(Request $request) {
// 获取 以下key组成的业务参数(数组格式),如果对应的key没有则忽略
$data = $request->only([
'app_id',
'return_url' ,
'notify_url',
'timestamp',
'subject', //商品标题
'out_trade_no', //订单号
'timeout_express', //订单有效时间,单位:分
'total_amount', //支付金额
'body',
'biz_content'
]);
try {
// 获取默认配置参数
$config = config('payment.alipay');
extract($config);
//公共请求参数
$array['app_id'] = $data['app_id'] ?? $app_id;
$array['method'] = 'alipay.trade.wap.pay';
//相当于标识了你的支付方式如:手机网站支付就用alipay.trade.wap.pay
$array['return_url'] = $data['return_url'] ?? 'https://anbin.work/';
//支付成功之后的返回地址
$array['notify_url'] = $data['notify_url'] ?? 'https://www.baidu.com/';
//支付成功的回调地址
$array['charset'] = 'UTF-8';
//编码格式
$array['sign_type'] = 'RSA2';
//签名方式
$array['version'] = '1.0';
//版本统一都是1.0
$array['timestamp'] = date('Y-m-d H:i:s');
//时间戳
$array['format'] = 'json';
//传输数据格式
//业务参数
$service['subject'] = $data['subject'] ?? "大礼包代理开通费用1";
$service['out_trade_no'] = $data['out_trade_no'] ?? time().mt_rand(1,10000);
$service['timeout_express'] = $data['timeout_express'] ?? '3m';
$service['total_amount'] = 0.01;
$service['product_code'] ='QUICK_WAP_WAY';
//销售产品码
$service['body'] = $data['body'] ?? '大礼包代理开通费用2';
//把业务参数封装到公共参数中
$array['biz_content']=json_encode($service, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$signStr = $this->getSignstr($array);
$array['sign']= $this->rsaSign($signStr,$prikey);
//拼装支付的form表单 ,生成访问表单 , 试过用get的方式访问,支付宝不认。有可能是sign参数超过了256位导致的。
$url = 'https://openapi.alipay.com/gateway.do';
$html="<form id='alipaysubmit' name='alipaysubmit' action='{$url}?charset={$array['charset']}' method='POST'>";
foreach($array as $k=>$v) {
$v = str_replace("'","'",$v);
//单引号会导致
$html.= "<input type='hidden' name='{$k}' value='{$v}'/>\n";
}
$html.="<input type='submit' value='ok' style='display:none;''></form>
<script>document.forms['alipaysubmit'].submit();</script>";
return response($html);
}
catch(\Exception $e) {
return response($e->getMessage());
}
}
/**
* 获取签名
* @param data 公共请求参数数组
* */
public function getSignstr(array $data) :string {
ksort($data);
//按key排序
$signStr='';
foreach($data as $k=>$v) {
$signStr.="&{$k}={$v}";
//这里只能用循环,尝试用http_build_query会导致访问失败
}
return substr($signStr,1);
}
/**
* 加签
* @param data 签名字符串
* @param prikey 私钥内容
* */
public function rsaSign(string $data, string$prikey) :string {
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($prikey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
openssl_sign($data, $sign,$res,OPENSSL_ALGO_SHA256);
return base64_encode($sign);
}
//当面付(扫码支付)
public function f2f(Request $request){
// 获取 以下key组成的业务参数(数组格式),如果对应的key没有则忽略
$data = $request->only([
'app_id',
'return_url' ,
'notify_url',
'timestamp',
'subject', //商品标题
'out_trade_no', //订单号
'timeout_express', //订单有效时间,单位:分
'total_amount', //支付金额
'body',
'biz_content'
]);
try {
// 获取默认配置参数
$config = config('payment.alipay');
extract($config);
//业务参数
$service = array(
'out_trade_no'=>$data['out_trade_no'] ?? time().mt_rand(1,10000), //订单号(自己生成的)
'total_amount'=>0.01, //单位 元
'subject'=>$data['subject'] ?? "大礼包代理开通费用3", //订单标题
'body' => $data['body'] ?? '大礼包代理开通费用4',
);
//公共参数
$array = array(
'app_id' => $app_id,
'method' => 'alipay.trade.precreate', //接口名称
'format' => 'JSON',
'charset'=>$charset, //编码格式
'sign_type'=>'RSA2', //签名类型
'timestamp'=>date('Y-m-d H:i:s'),
'version'=>'1.0', //默认签名验证使用1.0版本
'notify_url' => $data['notify_url'] ?? 'https://www.baidu.com/', //支付成功后的异步回调地址
'biz_content'=>json_encode($service), //封装的业务请求参数
);
$signStr = $this->getSignstr($array);
$array['sign']= $this->rsaSign($signStr,$prikey);
$res = $this->curlPost('https://openapi.alipay.com/gateway.do',$array);
$result = json_decode($res,true)['alipay_trade_precreate_response'];
if ($result['code'] && $result['code'] == '10000') {
return response($result['qr_code']);
} else {
return response($result['msg'] . ' : ' . $result['sub_msg']);
}
} catch(\Exception $e) {
return response($e->getMessage());
}
}
//curl post类型请求
public function curlPost($url = '', $postData = '', $options = array())
{
if (is_array($postData)) {
$postData = http_build_query($postData);
}
var_dump($postData);
$this_header = array("content-type:application/x-www-form-urlencoded;charset=UTF-8"); //设置curl使用UTF-8请求接口,否则支付宝默认以GBK形式处理,会造成后续异步回调业务无法处理
$ch = curl_init();
curl_setopt($ch,CURLOPT_HTTPHEADER,$this_header); //curl设置请求头信息
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
if (!empty($options)) {
curl_setopt_array($ch, $options);
}
//https请求 不验证证书和host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close($ch);
//转化成UTF-8编码
//$data = mb_convert_encoding($result,'UTF-8',['ASCII','UTF-8','GB2312','GBK']);
return $data;
}
}