• paypal对接


    paypal支付接口准备工作

    • 首先去申请一个paypal账号,https://www.paypal.com/
    • 申请完毕并登录,进入https://developer.paypal.com/developer/accounts/。即可看到你申请账号自动配属的两个测试账号,账号类别分别是:BUSINESS和PERSONAL,PERSONAL的账号里面有$9999,测试费用,表激动。
    • 下面去给两个账号设置密码,点击账号展开,然后点击Profile,会弹出账号信息框,里面可以设置密码等一堆属性。如果点击账号始终无法展开,请吐槽下paypal,然后F5再点。
    • 下面进入https://developer.paypal.com/developer/applications/申请APP,点击REST API apps栏目下面的Create App按钮,写进一个APP名称,然后选择一个测试账户作为此APP绑定的账号,如果你在上一步没有申请新的测试账号,那么这里默认就是选择了BUSINESS账号。
    • 然后打开创建的APP,可以看到APP的clientId和clientSecret。
    • paypal的测试环境域名为sandbox.paypal.com,正式域名为www.paypal.com。一下测试均为测试环境。

    至此准备工作差不多了,开始动代码。

    PayPal-PHP-SDK下载

    {
        "require" : {
            "paypal/rest-api-sdk-php" : "1.7.4"
        },
        "repositories": {
            "packagist": {
                "type": "composer",
                "url": "https://packagist.phpcomposer.com"
            }
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 切换至项目目录并执行composer install,PayPal-PHP-SDK安装完毕。
    • 因为PayPal-PHP-SDK里面的composer.json里面的require有psr/log,所以在在目录vendor下有三个文件夹:composer,paypal和psr。
    • 此时项目的目录结构如下,其中的app文件夹是下面实例化创建的文件夹。 
      这里写图片描述

    PayPal-PHP-SDK支付接口测试

    然后就简单了,PayPal-PHP-SDK里面有一个sample项目,里面有各种实例。 
    打开浏览器,输入http://~/rest-api-sdk-php/sample/index.php,“~”符号改为你自己的路径。 
    可以看到sample了,如下图: 
    这里写图片描述 
    图中的PayPal Payments - similar to Express Checkout in Classic APIs即为支付接口,对应的代码路径为~/rest-api-sdk-php/sample/payments/CreatePaymentUsingPayPal.php。

    PayPal Payments的逻辑大致如下:

    • 创建一个支付,发送到paypal服务端
    • paypal服务端返回一个用户授权地址
    • 转链到用户授权地址,用户授权
    • 用户授权完毕,paypal返回到客户端设置的execute地址,付款实现。

    实现如下: 
    ~/rest-api-sdk-php/sample/payments/CreatePaymentUsingPayPal.php有如下代码

    // ### Get redirect url
    // The API response provides the url that you must redirect
    // the buyer to. Retrieve the url from the $payment->getApprovalLink()
    // method
    // 获取到重定向地址
    $approvalUrl = $payment->getApprovalLink();
    
    // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
    // 将重定向地址打印出来
    ResultPrinter::printResult("Created Payment Using PayPal. Please visit the URL to Approve.".$approvalUrl, "Payment", "<a href='$approvalUrl' >$approvalUrl</a>", $request, $payment);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    点击 
    这里写图片描述 
    页面执行完毕,既看到paypal服务端返回的授权地址 
    这里写图片描述 
    转链到授权地址 
    这里写图片描述 
    用户登录授权之后 
    这里写图片描述 
    点击继续,返回用户设置的execute地址 
    这里写图片描述 
    至此,PayPal-PHP-SDK支付接口sample支付过程完毕。

    支付接口实例化

    在项目根目录创建app文件夹,创建几个必须的文件如下: 
    这里写图片描述 
    其中: 
    - payment.php,创建支付 
    - exec.php,执行支付,用户授权返回地址 
    - cancel.php,用户取消支付 
    - common.php,公共文件

    payment.php文件

    <?php
    // +----------------------------------------------------------------------
    // | Perfect Is Shit
    // +----------------------------------------------------------------------
    // | paypal支付DEMO
    // +----------------------------------------------------------------------
    // | Author: alexander <gt199899@gmail.com>
    // +----------------------------------------------------------------------
    // | Datetime: 2016-07-28 10:56:40
    // +----------------------------------------------------------------------
    // | Copyright: Perfect Is Shit
    // +----------------------------------------------------------------------
    require_once('./common.php');
    
    use PayPalApiAmount;
    use PayPalApiDetails;
    use PayPalApiItem;
    use PayPalApiItemList;
    use PayPalApiPayer;
    use PayPalApiPayment;
    use PayPalApiRedirectUrls;
    use PayPalApiTransaction;
    use PayPalApiShippingAddress;
    
    // ### Payer
    // A resource representing a Payer that funds a payment
    // For paypal account payments, set payment method
    // to 'paypal'.
    $payer = new Payer();
    $payer->setPaymentMethod("paypal");
    
    // ### Itemized information
    // (Optional) Lets you specify item wise
    // information
    $item1 = new Item();
    $item1->setName('test pro 1')
        ->setCurrency('USD')
        ->setQuantity(1)
        ->setSku("testpro1_01") // Similar to `item_number` in Classic API
        ->setPrice(20);
    $item2 = new Item();
    $item2->setName('test pro 2')
        ->setCurrency('USD')
        ->setQuantity(5)
        ->setSku("testpro2_01") // Similar to `item_number` in Classic API
        ->setPrice(10);
    
    $itemList = new ItemList();
    $itemList->setItems(array($item1, $item2));
    
    // 自定义用户收货地址,避免用户在paypal上账单的收货地址和销售方收货地址有出入
    // 这里定义了收货地址,用户在支付过程中就不能更改收货地址,否则,用户可以自己更改收货地址
    $address = new ShippingAddress();
    $address->setRecipientName('什么名字')
            ->setLine1('什么街什么路什么小区')
            ->setLine2('什么单元什么号')
            ->setCity('城市名')
            ->setState('浙江省')
            ->setPhone('12345678911')
            ->setPostalCode('12345')
            ->setCountryCode('CN');
    
    $itemList->setShippingAddress($address);
    
    
    // ### Additional payment details
    // Use this optional field to set additional
    // payment information such as tax, shipping
    // charges etc.
    $details = new Details();
    $details->setShipping(5)
        ->setTax(10)
        ->setSubtotal(70);
    
    // ### Amount
    // Lets you specify a payment amount.
    // You can also specify additional details
    // such as shipping, tax.
    $amount = new Amount();
    $amount->setCurrency("USD")
        ->setTotal(85)
        ->setDetails($details);
    
    // ### Transaction
    // A transaction defines the contract of a
    // payment - what is the payment for and who
    // is fulfilling it.
    $transaction = new Transaction();
    $transaction->setAmount($amount)
        ->setItemList($itemList)
        ->setDescription("Payment description")
        ->setInvoiceNumber(uniqid());
    
    // ### Redirect urls
    // Set the urls that the buyer must be redirected to after
    // payment approval/ cancellation.
    $baseUrl = getBaseUrl();
    $redirectUrls = new RedirectUrls();
    $redirectUrls->setReturnUrl("$baseUrl/exec.php?success=true")
        ->setCancelUrl("$baseUrl/cancel.php?success=false");
    
    // ### Payment
    // A Payment Resource; create one using
    // the above types and intent set to 'sale'
    $payment = new Payment();
    $payment->setIntent("sale")
        ->setPayer($payer)
        ->setRedirectUrls($redirectUrls)
        ->setTransactions(array($transaction));
    
    $payment->create($apiContext);
    
    $approvalUrl = $payment->getApprovalLink();
    // 打印出用户授权地址,这里仅仅实现支付过程,流程没有进一步完善。
    dump($approvalUrl);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116

    exec.php文件

    <?php
    // +----------------------------------------------------------------------
    // | Perfect Is Shit
    // +----------------------------------------------------------------------
    // | 执行支付DEMO
    // +----------------------------------------------------------------------
    // | Author: alexander <gt199899@gmail.com>
    // +----------------------------------------------------------------------
    // | Datetime: 2016-07-28 11:53:10
    // +----------------------------------------------------------------------
    // | Copyright: Perfect Is Shit
    // +----------------------------------------------------------------------
    set_time_limit(3600);
    require_once('./common.php');
    
    use PayPalApiAmount;
    use PayPalApiDetails;
    use PayPalApiExecutePayment;
    use PayPalApiPayment;
    use PayPalApiPaymentExecution;
    use PayPalApiTransaction;
    
    // ### Approval Status
    // Determine if the user approved the payment or not
    if (isset($_GET['success']) && $_GET['success'] == 'true') {
    
        // Get the payment Object by passing paymentId
        // payment id was previously stored in session in
        // CreatePaymentUsingPayPal.php
        $paymentId = $_GET['paymentId'];
        $payment = Payment::get($paymentId, $apiContext);
    
        // ### Payment Execute
        // PaymentExecution object includes information necessary
        // to execute a PayPal account payment.
        // The payer_id is added to the request query parameters
        // when the user is redirected from paypal back to your site
        $execution = new PaymentExecution();
        $execution->setPayerId($_GET['PayerID']);
    
        // ### Optional Changes to Amount
        // If you wish to update the amount that you wish to charge the customer,
        // based on the shipping address or any other reason, you could
        // do that by passing the transaction object with just `amount` field in it.
        // Here is the example on how we changed the shipping to $1 more than before.
        $transaction = new Transaction();
        $amount = new Amount();
        $details = new Details();
    
        $details->setShipping(5)
            ->setTax(10)
            ->setSubtotal(70);
    
        $amount->setCurrency('USD');
        $amount->setTotal(85);
        $amount->setDetails($details);
        $transaction->setAmount($amount);
    
        // Add the above transaction object inside our Execution object.
        $execution->addTransaction($transaction);
    
        try {
            // Execute the payment
            $result = $payment->execute($execution, $apiContext);
            echo "支付成功";
        } catch (Exception $ex) {
            echo "支付失败";
            exit(1);
        }
    
        return $payment;
    } else {
        echo "PayPal返回回调地址参数错误";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    cancel.php文件

    <?php
    // +----------------------------------------------------------------------
    // | Perfect Is Shit
    // +----------------------------------------------------------------------
    // | 取消支付DEMO
    // +----------------------------------------------------------------------
    // | Author: alexander <gt199899@gmail.com>
    // +----------------------------------------------------------------------
    // | Datetime: 2016-07-29 11:31:32
    // +----------------------------------------------------------------------
    // | Copyright: Perfect Is Shit
    // +----------------------------------------------------------------------
    echo "用户取消支付";
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    common.php文件

    <?php
    // +----------------------------------------------------------------------
    // | Perfect Is Shit
    // +----------------------------------------------------------------------
    // | 公共文件
    // +----------------------------------------------------------------------
    // | Author: alexander <gt199899@gmail.com>
    // +----------------------------------------------------------------------
    // | Datetime: 2016-07-28 11:55:30
    // +----------------------------------------------------------------------
    // | Copyright: ShowMore
    // +----------------------------------------------------------------------
    require_once('../vendor/autoload.php');
    
    use PayPalRestApiContext;
    use PayPalAuthOAuthTokenCredential;
    
    // 下面为申请app获得的clientId和clientSecret,必填项,否则无法生成token。
    $clientId = '';
    $clientSecret = '';
    $apiContext = new ApiContext(
        new OAuthTokenCredential(
            $clientId,
            $clientSecret
        )
    );
    $apiContext->setConfig(
        array(
            'mode' => 'sandbox',
            'log.LogEnabled' => true,
            'log.FileName' => '../PayPal.log',
            'log.LogLevel' => 'DEBUG', // PLEASE USE `INFO` LEVEL FOR LOGGING IN LIVE ENVIRONMENTS
            'cache.enabled' => true,
            // 'http.CURLOPT_CONNECTTIMEOUT' => 30
            // 'http.headers.PayPal-Partner-Attribution-Id' => '123123123'
            //'log.AdapterFactory' => 'PayPalLogDefaultLogFactory' // Factory class implementing PayPalLogPayPalLogFactory
        )
    );
    
    
    // 浏览器友好的变量输出
    function dump($var, $echo=true, $label=null, $strict=true) {
        $label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!$strict) {
            if (ini_get('html_errors')) {
                $output = print_r($var, true);
                $output = "<pre>" . $label . htmlspecialchars($output, ENT_QUOTES) . "</pre>";
            } else {
                $output = $label . print_r($var, true);
            }
        } else {
            ob_start();
            var_dump($var);
            $output = ob_get_clean();
            if (!extension_loaded('xdebug')) {
                $output = preg_replace("/]=>
    (s+)/m", "] => ", $output);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if ($echo) {
            echo($output);
            return null;
        }else
            return $output;
    }
    
    /**
     * ### getBaseUrl function
     * // utility function that returns base url for
     * // determining return/cancel urls
     *
     * @return string
     */
    function getBaseUrl()
    {
        if (PHP_SAPI == 'cli') {
            $trace=debug_backtrace();
            $relativePath = substr(dirname($trace[0]['file']), strlen(dirname(dirname(__FILE__))));
            echo "Warning: This sample may require a server to handle return URL. Cannot execute in command line. Defaulting URL to http://localhost$relativePath 
    ";
            return "http://localhost" . $relativePath;
        }
        $protocol = 'http';
        if ($_SERVER['SERVER_PORT'] == 443 || (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')) {
            $protocol .= 's';
        }
        $host = $_SERVER['HTTP_HOST'];
        $request = $_SERVER['PHP_SELF'];
        return dirname($protocol . '://' . $host . $request);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    支付接口实例测试

    执行payment.php文件,得到授权地址,如下: 
    这里写图片描述 
    转链到用户授权地址 
    这里写图片描述 
    用户登录授权,可以看到在我们设置过收货地址之后,支付收货地址是默认无法更改的。 
    这里写图片描述 
    用户点击继续,会转链到我们的支付成功回调地址exec.php。 
    这里写图片描述 
    用户点击取消并返回,会转链到我们的支付失败回调地址cancel.php 
    这里写图片描述 
    支付过后可进入sandbox账号中心查看是否有交易。 
    这里写图片描述 
    测试的款项都在这里,有个问题,sandbox上面的交易时间总比我这边晚一天,比如今天是7月29日完成的交易,但是在sandbox里面显示的都是7月28日。不知道是不是个BUG。

    至此,PayPal-PHP-SDK的支付接口OK。 
    可以对PayPal-PHP-SDK底层代码进行进一步研究,有时间再弄

  • 相关阅读:
    easyui源码翻译1.32--Droppable(放置)
    easyui源码翻译1.32--Draggable(拖动)
    easyui源码翻译1.32--Dialog(对话框窗口)
    easyui源码翻译1.32--DateTimeBox(日期时间输入框)
    easyui源码翻译1.32--DateBox(日期输入框)
    easyui源码翻译1.32--ComboTree(树形下拉框)
    easyui源码翻译1.32--ComboGrid(数据表格下拉框)
    我不曾忘记的初心-大厂小厂
    我不曾忘记的初心-屌丝逆袭
    我不曾忘记的初心-愿天堂没有代码
  • 原文地址:https://www.cnblogs.com/huixuexidezhu/p/8436244.html
Copyright © 2020-2023  润新知