当前位置: 首页 > article >正文

paypal php 实现详细攻略

一、准备工作
登录 https://www.paypal.com/ 注册一个主账号(选择个人账号、企业账后都可)
申请完成后登录https://developer.paypal.com/ 在后台右侧菜地点击“Accounts”,可以看到系统自动给分配的两个沙箱环境的账号。类型为Personal是个人账号、类型为Business是商家账号。点进去可以看到密码
开启PDT设置同步回调地址(这步拿到at_token return回调使用)
用系统分配的卖家账号登录沙箱地址https://www.sandbox.paypal.com/

二: 调用接口,获取token,创建订单,生成支付链接,然后捕获订单确认付款,处理回调事件。

Developer Dashboard 切换测试模式和正式模式的链接

三:修改回调事件在选择的应用,点击进去后可以修改增加,捕获订单接口在回调的时候调用

参考链接: 【支付】PayPal支付通道 Java对接 (下单 付款 确认 退款 查询 回调)_java对接paypal-CSDN博客

php PayPal 支付/回调 - 加菲猫and大白 - 博客园

/**
 * 统一下单接口
 * @param $order
 * @param string $trade_type
 * @return array
 */
function create_order_bak()
{
    $domain = $this->request->domain();
    $order['order_no'] = 10191;
    $arr = [
        'purchase_units' => [
            [
                'custom_id' => 1,
                'reference_id' => $order['order_no'],//订单ID
                'amount' => [
                    'currency_code' => 'USD',
                    'value' => 1
                ]
            ]
        ],
        'intent' => 'CAPTURE',
        'payment_source' => [
            'paypal' => [
                'experience_context' => [
                    'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
                    'payment_method_selected' => 'PAYPAL',
                    'brand_name' => 'TEST',
                    'landing_page' => 'GUEST_CHECKOUT',//直接付款
                    'user_action' => 'PAY_NOW',
                    'return_url' => 'https://1688order.com',//付款后回调地址
                    'cancel_url' => 'https://1688order.com'//取消付款后回调地址
                ]
            ]
        ]
    ];

    $result = $this->post(
        self::ONLINE_USEEPAY_SANDBOX_ENDPOINT.'/v2/checkout/orders',
        ['Content-Type: application/json','Authorization: Bearer '.$this->getPaypalToken(),'PayPal-Request-Id: '.'TEST-'.$order['order_no']],
        json_encode($arr)
    );
   // Log::write('创建订单返回信息:'.var_export($result, true));
    if(isset($result['id'])){
        return array('code' => 1, 'msg' => '创建订单成功', 'data' => $result);
    }else{
     //   return array('code' => 0, 'data' => $result['message']);
    }


}

/**
 * id 是下单的时候生成的订单的ID
 * paypal 回调后 捕获订单付款
 */
function paypalOrderCapture($id){

    $result = $this->post(
        self::ONLINE_USEEPAY_SANDBOX_ENDPOINT.'/v2/checkout/orders/'.$id.'/capture',
        ['Content-Type: application/json','Authorization: Bearer '.$this->getPaypalToken(),'PayPal-Request-Id: '.'TEST-'.$id]
    );
    return $result['status'] == 'COMPLETED' ? $result : false;

}

/**
 * 获取token,一般返回来的access token有效时是9个小时
 **/
function getPaypalToken(){

    $paypal_token_config = cache("paypal-token-new");

    $end_time = time();


    if($paypal_token_config)
    {
        $result = $paypal_token_config;
        $results = json_decode($result, true);
        $end_time = $results['time'] + $results['expires_in'];
    }

    if($end_time - time() < 1800){ //更新access token
        $result = $this->post(
            self::ONLINE_USEEPAY_SANDBOX_ENDPOINT.'/v1/oauth2/token',
            [
                'Content-Type: application/x-www-form-urlencoded',
                'Authorization:Basic '.base64_encode(self::ONLINE_CLEINTID.":".self::ONLINE_CLIENTSECRET)
            ],
            http_build_query(['grant_type' => 'client_credentials'])
        );

        if(isset($result['app_id'])){
            $result['time'] = time();
            cache("paypal-token-new",json_encode($result),3600);
        }
    }

    return isset($results['access_token']) ? $results['access_token'] : false;
}

/**
 * 发起POST请求
 */
public function post($url, $headers, $request = array())
{

    $header_res = [];
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_HEADERFUNCTION,
        function ($curl, $header) use (&$header_res) {
            $len = strlen($header);
            $header = explode(':', $header, 2);
            if (count($header) < 2) // ignore invalid headers
                return $len;

            $header_res[strtolower(trim($header[0]))][] = trim($header[1]);

            return $len;
        }
    );

    $response_data = curl_exec($curl);
    curl_close($curl);

    $result = json_decode($response_data, true);

    return $result;
}
//回调地址
public function notify_order(){
    Log::write('paypal 支付进来了');
    $payload = @file_get_contents('php://input');
    // 调用 record() 方法记录日志
   // Log::write('content'.var_export($payload, true));
    $ret = json_decode($payload, true);
    Log::write('数组格式返回:'.var_export($ret, true));
   // Log::write('id'.var_export($ret['resource']['id'], true));
   // Log::write('status'.var_export($ret['resource']['status'], true));
    $order_id = $ret['resource']['id'];
    $result = $this->paypalOrderCapture($order_id);
    Log::write('确认付款后返回结果:'.var_export($result, true));
    $captureId = $result['purchase_units'][0]['payments']['captures'][0]['id'];//捕获ID,在退款的时候使用
    Log::write('确认支付后的支付状态是:'.var_export($result['status'], true));
    Log::write('捕获ID是:'.var_export($captureId, true));

    $web_order_id = $result['purchase_units'][0]['reference_id'];//网站下单的订单ID
    Log::write('网站下单的订单ID:'.var_export($web_order_id, true));

    $buy_type = $result['purchase_units'][0]['payments']['captures'][0]['custom_id'];//下单类型
    Log::write('网站下单类型:'.var_export($buy_type, true));

    //如果确认支付成功
    if ($result['status'] == 'COMPLETED'){
        //调用修改订单状态后续逻辑
        $res =  PayNotifyLogic::handle('order_buy', $web_order_id, ['buy_type'=>$buy_type,'payment_intent_id'=>$captureId]);

        if ($res) {
            $this->success('success', url('/pc/user/order/detail', ['id' => $order_id]));
        }

    }else{
        Log::write('确认付款失败返回结果:'.var_export($result, true));

    }

}

http://www.kler.cn/news/353808.html

相关文章:

  • 4 登录接口实现(Vue3+Spring boot+mysql)
  • LeetCode322:零钱兑换
  • 图论刷题
  • 好用的python相关的AI工具Bito介绍
  • Linux多任务编程(网络编程-数据库篇)
  • 【wpf】05 几种容器动态创建控件的对比
  • 【c++篇】:初识c++--编程新手的快速入门之道(二)
  • MyBatisPlus笔记之逻辑删除、枚举处理器、JSON处理器
  • WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析五
  • 微服务经典应用架构图
  • QUIC 协议的优势
  • Node.js基础与应用
  • 力扣面试150 交错字符串 二维DP
  • 数学建模算法与应用 第7章 数理统计与方法
  • Python | Leetcode Python题解之第482题秘钥格式化
  • 深入理解Dubbo原理鱼实现,提升职场竞争力
  • 从0开始学Python-day8
  • Unity3D 如何实现从任意位置与方向出发后按规定方向到达目标点详解
  • C#从零开始学习(如何构建应用)
  • Java:类和对象