早睡早起,方能养生!
Sleep early rise early, square can preserve one's health!

国外支付Stripe PHP

super
2020-11-04 18:37
views 596

Stripe支付 :

注册账户:https://dashboard.stripe.com/register


预设结账页面 (Prebuilt Checkout page

https://stripe.com/docs/payments/accept-a-payment

checkout-preview.png

跳转到Stripe的付款页面结算,Stripe将付款结果发送给服务器(类似微信支付的回调)

上图的商品信息是自己传入的(图片,文字及价格)

image.png

不必理会此处的“产品”,上面的功能用不到这个


1)安装Stripe,本节以ThinkPHP5.1为例,PHP7.1

composer require stripe/stripe-php

2)秘钥

获取地址: https://dashboard.stripe.com/test/apikeys

Html秘钥是Html页面所使用的秘钥

PHP秘钥是PHP Code里面所使用的秘钥

image.png

3)Code

PHP Code:

<?php

namespace app\index\controller;

use Stripe\Stripe;
use think\Db;

class Pay extends Common
{
    private static $key;
    
    public function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub
        self::$key = 'sk_test_51HjJtrB1etHLMjYqENRyuj83dztQqbom5T1apAK5OXXXXXXXXXXXXXXXXXXXXXXXX1pVmlTxAbaPEigL00goDSLuUm';
    }

    /**
     * Stripe支付
     * @access private
     * @author super
     * @date 2020-11-04
     * @param array $product 商品信息
     * @param int|float $amount 支付金额
     * @param array $pay_type 支付类型
     * @param string $currency 货币类型 小写
     * @return string
     */
    private static function stripePay($product, $amount, $pay_type = ['card'], $currency = 'aud')
    {
        require __DIR__ . '/../../../vendor/autoload.php';

        \Stripe\Stripe::setApiKey(self::$key);

        header('Content-Type: application/json');

        $YOUR_DOMAIN = 'https://rongsp.com';

        $checkout_session = \Stripe\Checkout\Session::create([
            'payment_method_types' => $pay_type,
            'line_items' => [[
                'price_data' => [
                    'currency' => $currency,
                    'unit_amount' => $amount,
                    'product_data' => $product
                ],
                'quantity' => 1,
            ]],
            'mode' => 'payment',
            'success_url' => $YOUR_DOMAIN . '/success.html',
            'cancel_url' => $YOUR_DOMAIN . '/cancel.html',
        ]);
        return ['id' => $checkout_session->id, 'payment_intent' => $checkout_session->payment_intent];
    }
    
    public function pay()
    {
        // 订单ID
        $order_id = input('order_id');
        
        // 查询订单详情
        $order_info = Db::name('orders')->where('order_id', $order_id)->find();

        $product = [
            'name' => 'Order Number:' . $order_info['order_sn'] ,
            'images' => [
                'https://rongsp.com/Super/favicon.ico'
            ]
        ];
        $amount = $order_info['price'] * 100;

        $result = self::stripePay($product, $amount);
        if (!isset($result['id']) || !isset($result['payment_intent'])) {
            returnData(500, 'ERROR! BUSY NETWORK!');
        }

        $update = Db::name('orders')->where('order_id', $order_info['order_id'])->update(['payment_intent' => $result['payment_intent']]);
        if (!$update) {
            returnData(500, 'ERROR! BUSY NETWORK!');
        }

        returnData(200, 'SUCCESS!', ['id' => $result['id']]);
    }

    // 支付成功通知  见5)
    public function successNotify()
    {
        // Set your secret key. Remember to switch to your live secret key in production!
        // See your keys here: https://dashboard.stripe.com/account/apikeys
        \Stripe\Stripe::setApiKey(self::$key);
        
        $payload = @file_get_contents('php://input');
        $event = null;
        
        try {
            $event = \Stripe\Event::constructFrom(
                json_decode($payload, true)
            );
        } catch(\UnexpectedValueException $e) {
            // Invalid payload
            http_response_code(400);
            exit();
        }

        // Handle the event
        switch ($event->type) {
            case 'charge.succeeded':
                
                $succeeded = $event->data->object;
                
                if ($succeeded->status == 'succeeded'){

                    $payment_intent = $succeeded->payment_intent;

                    // 查询订单详情
                    $order_info = Db::name('orders')->where('payment_intent', $payment_intent)->find();
                    if (!$order_info) {
                        http_response_code(200);exit;
                    }

                    if ($order_info['status'] != 0) {
                        return;
                    }

                    // 订单标记为处理中
                    Db::name('orders')->where('order_id', $order_info['order_id'])->update(['pay_time' => time(), 'status' => 3]);

                    // 订单处理
                    // ...

                    // 标记为处理完成
                    Db::name('orders')->where('order_id', $order_info['order_id'])->update(['status' => 1]);
                }
                break;
            default:
                echo 'Received unknown event type ' . $event->type;
        }
        http_response_code(200);
    }
}

Html Code:

<html>
  <head>
    <title>Buy test</title>
    <script src="https://js.stripe.com/v3/"></script>
  </head>
  <body>
    <button id="checkout-button">Checkout</button>

    <script type="text/javascript">
      // Create an instance of the Stripe object with your publishable API key
      var stripe = Stripe('pk_test_51HjJtrB1etHLMjYqPgu55dKoPIDnmh2H8Z96TiXXXXXXXXXXXXXXXXXXXXXXXzvuKWr70xq8c0kNpVzD6r00g3oSMoE5');
      var checkoutButton = document.getElementById('checkout-button');

      checkoutButton.addEventListener('click', function() {
        // Create a new Checkout Session using the server-side endpoint you
        // created in step 3.
        fetch('/api.php/Pay/pay/order_id/1', {
          method: 'POST',
        })
        .then(function(response) {
          return response.json();
        })
        .then(function(session) {
            
            console.log(session)
            
          return stripe.redirectToCheckout({ sessionId: session.id });
        })
        .then(function(result) {
          // If `redirectToCheckout` fails due to a browser or network
          // error, you should display the localized error message to your
          // customer using `error.message`.
          if (result.error) {
            alert(result.error.message);
          }
        })
        .catch(function(error) {
          console.error('Error:', error);
        });
      });
    </script>
    
  </body>
</html>

4)测试

Html:

image.png

点击Checkout

image.png

5)接收支付结果通知

image.png

点击右上角“添加端点”(这里我已经添加了一个)

添加一个可在外部访问的URL,事件选择charge.succeeded(支付成功通知)

image.png

支付通知相关代码已在上方贴出(PHP Code)

上线要切换正式的秘钥(Html 及PHP秘钥)

tip:鼠标置于代码块上 Shift + 鼠标滚轮 可左右滑动代码

-禁止转载-


分享
0 条讨论
top