Thinkphp5.1贝宝(Paypal)支付接入

Thinkphp5.1 paypal Thinkphp5 paypal tp5 paypal

最初打算用PayPal官方的API做,但是,发现回调的信息有点少,所以就改成了form提交的,这里记录一下:

1.先去PayPal官网申请账号,然后进入开发者中心https://developer.paypal.com/developer/accounts/,会看到已经创建好的测试账号,有买家的和卖家的

9f/437eccfc02d479b540565adbd144c9.png

然后创建app,就可以看到生成的clientId和clientSecret:

91/cb0d1ae9646f0980de6bb9b1d93480.png


然后设置 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