最初打算用PayPal官方的API做,但是,发现回调的信息有点少,所以就改成了form提交的,这里记录一下:
1.先去PayPal官网申请账号,然后进入开发者中心https://developer.paypal.com/developer/accounts/,会看到已经创建好的测试账号,有买家的和卖家的
然后创建app,就可以看到生成的clientId和clientSecret:
然后设置 SANDBOX WEBHOOKS ,把Event types全选(免得漏掉什么),Webhook Url必须是https的,没有的可以去阿里云申请免费证书。
2.程序部分:
我用的是Thinkphp5.1版本,控制器里具体如下:
//贝宝支付
public function paypal(){
$id = input('id');
$row = db('order')->where(['id'=>$id])->find();
$baseUrl = getHostDomain();
$returnUrl = $baseUrl.config('app.paypal.returnUrl');
$notifyUrl = $baseUrl.config('app.paypal.notifyUrl');
$cancelUrl = $baseUrl.config('app.paypal.cancelUrl');
$business = config('app.paypal.business');
$paypalUrl = config('app.paypal.paypalUrl');
$this->assign('returnUrl', $returnUrl);
$this->assign('notifyUrl', $notifyUrl);
$this->assign('cancelUrl', $cancelUrl);
$this->assign('paypalUrl', $paypalUrl);
$this->assign('business', $business);
$this->assign('row', $row);
return $this->fetch();
}
模版内容如下:
<form action="{$paypalUrl}" method="POST" name="form_starPay">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="{$business}">
<input type="hidden" name="item_name" value="{$row.exhibition_title}">
<input type="hidden" name="item_number" value="{$row.order_number}">
<input type="hidden" name="amount" value="{$row.insurance_price}">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="return" value="{$returnUrl}">
<input type="hidden" name="notify_url" value="{$notifyUrl}">
<input type="hidden" name="cancel_return" value="{$cancelUrl}">
<input type="hidden" name="invoice" value="{$row.order_number}">
<input type="hidden" name="charset" value="utf-8">
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="rm" value="2">
<input type="image" name="submit" src="https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif" />
</form>
Jumping to Paypal, please wait...
<script>
function sub(){
document.form_starPay.submit();
}
onload(sub())
</script>
回调和付款结果:
/**
* @function paypalNotifyCallback
* @intro paypal回调
* @return string
*/
public function paypalNotifyCallback()
{
if(!$_POST){
die('error');
}
$post_data = $_POST;
paypalNotifyCallBackLog(json_encode($post_data));//记录日志
$post_data['cmd'] = '_notify-validate';
$url = config('app.paypal.paypalUrl');//支付异步验证地址
$res = https_request($url,$post_data);
importLog($res);//记录日志
if (!empty($res)) {
if (strcmp($res, "VERIFIED") == 0) {
if ($post_data['payment_status'] == 'Completed' || $post_data['payment_status'] == 'Pending') {
$paypalRow = db('paypal_record')->where(['invoice'=>$post_data['invoice']])->find();
$data = $post_data;
$data['payment_date'] = strtotime($data['payment_date']);
if(!$paypalRow){
db('paypal_record')->strict(false)->insertGetId($data);
}else{
db('paypal_record')->where(['invoice'=>$post_data['invoice']])->update($data);
}
//付款完成,这里修改订单状态
$data = [];
$data['status'] = 1;
$data['pay_time'] = strtotime($post_data['payment_date']);
db('order')->where(['order_number'=>$post_data['invoice']])->update($data);
$row = db('order')->where(['order_number'=>$post_data['invoice']])->find();
return 'success';
}
} elseif (strcmp($res, "INVALID") == 0) {
//未通过认证,有可能是编码错误或非法的 POST 信息
return 'fail';
}
} else {
//未通过认证,有可能是编码错误或非法的 POST 信息
return 'fail';
}
}
/**
* @function paypalResult
* @intro 贝宝支付结果
* @return string
*/
public function paypalResult()
{
$status = input('status');
$paypalRow = [];
if($status == 1){
$data = $_POST;
paypalNotifyCallBackLog(json_encode($data));//记录日志
$apiContext = paypalApiContext();
$paypalRow = db('paypal_record')->alias('p')->join('order o','p.invoice=o.order_number')->where(['p.invoice'=>$data['invoice']])->field('p.*,o.contact')->find();
if(!$paypalRow){
$status = 0;
}
}
$this->assign('status', $status);
$this->assign('paypalRow', $paypalRow);
return $this->fetch();
}
这里贴一下PayPal的数据表:
--
-- 表的结构 `yaoda_paypal_record`
--
CREATE TABLE `yaoda_paypal_record` (
`id` int(11) NOT NULL,
`payment_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付类型',
`payment_date` int(10) NOT NULL COMMENT '支付时间',
`payment_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付状态',
`payment_fee` decimal(9,2) NOT NULL,
`address_status` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL,
`payer_status` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '付款人认证状态',
`first_name` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓',
`last_name` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '名',
`payer_email` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '付款email',
`payer_id` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '付款人ID',
`address_name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
`address_country` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '国家',
`address_country_code` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '国家代码',
`address_zip` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '国家邮编',
`address_state` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '区',
`address_city` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '城市',
`address_street` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '街道',
`business` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务邮箱',
`receiver_email` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '收款邮箱',
`receiver_id` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '收款id',
`residence_country` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
`item_name` varchar(200) COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
`item_number` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品编号',
`quantity` int(3) NOT NULL COMMENT '数量',
`shipping_discount` decimal(9,2) NOT NULL,
`tax` decimal(9,2) DEFAULT NULL COMMENT '税费',
`mc_currency` varchar(20) COLLATE utf8mb4_general_ci NOT NULL COMMENT '货币类型',
`mc_fee` decimal(9,2) NOT NULL,
`mc_gross` decimal(9,2) NOT NULL,
`mc_gross_1` decimal(9,2) DEFAULT NULL,
`insurance_amount` decimal(9,2) NOT NULL,
`txn_type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`txn_id` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`discount` decimal(9,2) NOT NULL,
`notify_version` varchar(10) COLLATE utf8mb4_general_ci NOT NULL,
`custom` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
`invoice` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`test_ipn` int(1) NOT NULL COMMENT '是否测试',
`verify_sign` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '签名',
`shipping_method` varchar(20) COLLATE utf8mb4_general_ci NOT NULL,
`transaction_subject` text COLLATE utf8mb4_general_ci,
`payment_gross` decimal(9,2) NOT NULL COMMENT '付款金额',
`ipn_track_id` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`protection_eligibility` varchar(50) COLLATE utf8mb4_general_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='paypal付款记录';
有问题可以留言!
参考:
https://blog.csdn.net/qq_31600613/article/details/82225227
vue2 Implicit conversion from float int loses precision php8Implicit Mysql8新增用户,mysql8配置权限,mysql8配置,mysql8配置文件 Linux命令,scp,scp命令,Linux复制 git commit git add centos git 搭建FTP,Linux FTP,禁止FTP登录ssh 上传文件,阿里云OSS上传,文件上传到OSS,OSS文件上传,OSS上传 微信支付,微信支付V3,PHP微信支付,微信nativePay支付,微信jsapi支付 微信支付,微信支付V3,PHP微信支付 bootstrap4 modal, lavarel The subversion command line tools are no longer provided by Xcode. 银联支付,tp5.1银联支付 支付宝即时到账,PHP支付宝 system libzip must be upgraded to version >= 0.11 CMake 3.0.2 or higher is required