最初打算用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