StripeCheckout.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. namespace App\Payments;
  3. use Stripe\Stripe;
  4. use Stripe\Checkout\Session;
  5. class StripeCheckout {
  6. public function __construct($config)
  7. {
  8. $this->config = $config;
  9. }
  10. public function form()
  11. {
  12. return [
  13. 'currency' => [
  14. 'label' => '货币单位',
  15. 'description' => '',
  16. 'type' => 'input',
  17. ],
  18. 'stripe_sk_live' => [
  19. 'label' => 'SK_LIVE',
  20. 'description' => 'API 密钥',
  21. 'type' => 'input',
  22. ],
  23. 'stripe_pk_live' => [
  24. 'label' => 'PK_LIVE',
  25. 'description' => 'API 公钥',
  26. 'type' => 'input',
  27. ],
  28. 'stripe_webhook_key' => [
  29. 'label' => 'WebHook 密钥签名',
  30. 'description' => '',
  31. 'type' => 'input',
  32. ]
  33. ];
  34. }
  35. public function pay($order)
  36. {
  37. $currency = $this->config['currency'];
  38. $exchange = $this->exchange('CNY', strtoupper($currency));
  39. if (!$exchange) {
  40. abort(500, __('Currency conversion has timed out, please try again later'));
  41. }
  42. $params = [
  43. 'success_url' => $order['return_url'],
  44. 'cancel_url' => $order['return_url'],
  45. 'client_reference_id' => $order['trade_no'],
  46. 'line_items' => [
  47. [
  48. 'price_data' => [
  49. 'currency' => $currency,
  50. 'product_data' => [
  51. 'name' => $order['trade_no']
  52. ],
  53. 'unit_amount' => floor($order['total_amount'] * $exchange)
  54. ],
  55. 'quantity' => 1
  56. ]
  57. ],
  58. 'mode' => 'payment'
  59. // 'customer_email' => $user['email'] not support
  60. ];
  61. Stripe::setApiKey($this->config['stripe_sk_live']);
  62. try {
  63. $session = Session::create($params);
  64. } catch (\Exception $e) {
  65. info($e);
  66. abort(500, "Failed to create order. Error: {$e->getMessage}");
  67. }
  68. return [
  69. 'type' => 1, // 0:qrcode 1:url
  70. 'data' => $session->url
  71. ];
  72. }
  73. public function notify($params)
  74. {
  75. \Stripe\Stripe::setApiKey($this->config['stripe_sk_live']);
  76. try {
  77. $event = \Stripe\Webhook::constructEvent(
  78. file_get_contents('php://input'),
  79. $_SERVER['HTTP_STRIPE_SIGNATURE'],
  80. $this->config['stripe_webhook_key']
  81. );
  82. } catch (\Stripe\Error\SignatureVerification $e) {
  83. abort(400);
  84. }
  85. switch ($event->type) {
  86. case 'checkout.session.completed':
  87. $object = $event->data->object;
  88. if ($object->payment_status === 'paid') {
  89. return [
  90. 'trade_no' => $object->client_reference_id,
  91. 'callback_no' => $object->payment_intent
  92. ];
  93. }
  94. break;
  95. case 'checkout.session.async_payment_succeeded':
  96. $object = $event->data->object;
  97. return [
  98. 'trade_no' => $object->client_reference_id,
  99. 'callback_no' => $object->payment_intent
  100. ];
  101. break;
  102. default:
  103. abort(500, 'event is not support');
  104. }
  105. die('success');
  106. }
  107. private function exchange($from, $to)
  108. {
  109. $result = file_get_contents('https://api.exchangerate.host/latest?symbols=' . $to . '&base=' . $from);
  110. $result = json_decode($result, true);
  111. return $result['rates'][$to];
  112. }
  113. }