国外支付Stripe PHP
Stripe支付 :
注册账户:https://dashboard.stripe.com/register
支付类型: 预设结账页面 (Prebuilt Checkout page)
简介:跳转到stripe结算页面进行支付
文档:
https://stripe.com/docs/payments/accept-a-payment
示例图片:
跳转到Stripe的付款页面结算(如上图),Stripe将付款结果发送给我们的服务器(类似微信支付的回调,url需指定)
图上的商品信息(图片,文字及价格)提前由API传入,生成session_id,由web页面 js 跳转即可
不必理会此处的“产品”,上面的功能用不到这个
1)安装Stripe,本节以ThinkPHP5.1为例,PHP7.1
composer require stripe/stripe-php
2)秘钥
获取地址: https://dashboard.stripe.com/test/apikeys
Html秘钥是Html页面所使用的秘钥
PHP秘钥是PHP Code下单时所使用的秘钥
3)PHP代码
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();
self::$key = 'sk_test_51HjJtrB1etHLMjYqENRyuj83dztQqbom5T1apAK5OXXXXXXXXX (你的PHP密钥) XXXXXXXXXXXXXXX1pVmlTxAbaPEigL00goDSLuUm';
}
/**
* Stripe支付
* @access private
* @author super
* @date 2020-11-04
* @param array $product 商品信息
* @param int|float $amount 支付金额
* @param array $pay_type 支付类型
* @param string $currency 货币类型 小写
* @return array
*/
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', // 支付成功后跳转url
'cancel_url' => $YOUR_DOMAIN . '/cancel.html', // 支付失败后跳转url
]);
return ['id' => $checkout_session->id, 'payment_intent' => $checkout_session->payment_intent]; // 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']]);
}
// 支付成功通知
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);
}
}
web 代码:
<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_51HjJtrB1etHLMjYqPgu55dKoPIDnmh2H8Z96TiXXXXXXXXXX( 这里填上你的Html密钥 )XXXXXXXXXXXXXzvuKWr70xq8c0kNpVzD6r00g3oSMoE5');
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)测试
页面:
点击 Checkout 后跳转到
5)接收支付结果通知
点击右上角“添加端点”(已经添加了一个)
添加一个可在外部访问(不需要Token或Session等凭证)的URL,事件选择charge.succeeded(支付成功通知)
支付通知相关代码见上方 PHP 代码
(以上是由)stripe提供的测试环境进行记录(调试模式可任意付款,便于测试)
如果使用了测试环境(密钥),记得上线要切换正式环境的 Html 及 PHP秘钥
---禁止转载---
#21
#22
#23
#24