lunarphp / stripe
Lunar 的 Stripe 支付驱动程序。
Requires
- php: ^8.2
- lunarphp/core: 1.0.0-beta.2
- stripe/stripe-php: ^14.4
- dev-main
- 1.x-dev
- 1.0.x-dev
- 1.0.0-beta.2
- 1.0.0-beta.1
- 1.0.0-alpha.37
- 1.0.0-alpha.36
- 1.0.0-alpha.35
- 1.0.0-alpha.34
- 1.0.0-alpha.33
- 1.0.0-alpha.32
- 1.0.0-alpha.31
- 1.0.0-alpha.30
- 1.0.0-alpha.29
- 1.0.0-alpha.28
- 1.0.0-alpha.27
- 1.0.0-alpha.26
- 1.0.0-alpha.25
- 1.0.0-alpha.24
- 1.0.0-alpha.23
- 1.0.0-alpha.22
- 1.0.0-alpha.21
- 1.0.0-alpha.20
- 1.0.0-alpha.19
- 1.0.0-alpha.18
- 1.0.0-alpha.17
- 1.0.0-alpha.16
- 1.0.0-alpha.15
- 1.0.0-alpha.14
- 1.0.0-alpha.13
- 1.0.0-alpha.12
- 1.0.0-alpha.11
- 1.0.0-alpha.10
- 1.0.0-alpha.9
- 1.0.0-alpha.8
- 1.0.0-alpha.7
- 1.0.0-alpha.6
- 1.0.0-alpha.5
- 1.0.0-alpha.4
- 1.0.0-alpha.3
- 1.0.0-alpha.2
- 1.0.0-alpha.1
- 0.8.x-dev
- 0.8.0
- 0.7.x-dev
- 0.7.0
- 0.7.0-rc.2
- 0.7.0-rc.1
- 0.6.x-dev
- 0.6.1
- 0.6.0
- 0.5.x-dev
- 0.5.0
- 0.4.x-dev
- 0.4.0
- 0.3.x-dev
- 0.3.0
- 0.2.x-dev
- 0.2.0
- 0.2-rc1
- 0.1.x-dev
- 0.1.1
- 0.1.0
- 0.1.0-rc.1
- dev-1.0.0-beta
- dev-1.0.0-alpha
- dev-alecritson-patch-1
- dev-feat/stripe-refactor
- dev-feat/webhooks
This package is auto-updated.
Last update: 2024-09-17 08:45:38 UTC
README
此插件使您能够在 Lunar 店面上启用 Stripe 支付。
Alpha 版本
此插件目前处于 Alpha 版,尽管我们已尽一切努力确保其按预期工作,但只有在添加更多测试并证明其有效性后,才会将其视为 Alpha 版本。
所需测试
- 从 Stripe 获取成功的收费响应。
- 从 Stripe 获取失败的收费响应。
- 测试
手动
配置是否做出适当反应。 - 测试
自动
配置是否做出适当反应。 - 确保交易正确存储在数据库中。
- 确保在使用同一购物车时,支付意图不会重复。
- 确保根据 Stripe 的响应返回适当的响应。
- 测试退款和部分退款创建预期的交易。
- 确保我们可以手动释放付款或部分付款并处理不同的响应。
最低要求
- Lunar
1.x
- 拥有具有密钥的 Stripe 账户
可选要求
- Laravel Livewire(如果使用前端组件)
- Alpinejs(如果使用前端组件)
- JavaScript 框架
安装
需要 composer 包
composer require lunarphp/stripe
发布配置
这将发布配置到 config/lunar/stripe.php
。
php artisan vendor:publish --tag=lunar.stripe.config
发布视图(可选)
Lunar Stripe 包含一些辅助组件,您可以在结账时使用,如果您打算编辑它们提供的视图,则可以发布它们。
php artisan vendor:publish --tag=lunar.stripe.components
启用驱动程序
在 config/lunar/payments.php
中设置驱动程序
<?php return [ // ... 'types' => [ 'card' => [ // ... 'driver' => 'stripe', ], ], ];
添加您的 Stripe 凭证
请确保您已在 config/services.php
中设置了 Stripe 凭证
'stripe' => [ 'key' => env('STRIPE_SECRET'), 'public_key' => env('STRIPE_PK'), 'webhooks' => [ 'lunar' => env('LUNAR_STRIPE_WEBHOOK_SECRET'), ], ],
密钥可以在您的 Stripe 账户中找到 https://dashboard.stripe.com/apikeys
配置
以下是在 config/lunar/stripe.php
中使用的此包的可用的配置选项列表
后端使用
创建支付意图
use \Lunar\Stripe\Facades\Stripe; Stripe::createIntent(\Lunar\Models\Cart $cart, $options = []);
此方法将根据购物车创建 Stripe 支付意图,并将生成的 ID 添加到元数据以供以后检索。如果购物车已存在支付意图,则将从 Stripe 获取它并返回该意图,以避免创建重复的支付意图。
您可以通过传递任何所需的附加参数,默认情况下发送以下参数:
[ 'amount' => 1099, 'currency' => 'GBP', 'automatic_payment_methods' => ['enabled' => true], 'capture_method' => config('lunar.stripe.policy', 'automatic'), // If a shipping address exists on a cart // $shipping = $cart->shippingAddress 'shipping' => [ 'name' => "{$shipping->first_name} {$shipping->last_name}", 'phone' => $shipping->contact_phone, 'address' => [ 'city' => $shipping->city, 'country' => $shipping->country->iso2, 'line1' => $shipping->line_one, 'line2' => $shipping->line_two, 'postal_code' => $shipping->postcode, 'state' => $shipping->state, ], ] ]
$paymentIntentId = $cart->meta['payment_intent']; // The resulting ID from the method above.
$cart->meta->payment_intent;
获取现有的支付意图
use \Lunar\Stripe\Facades\Stripe; Stripe::fetchIntent($paymentIntentId);
同步现有的意图
如果已创建支付意图并且购物车有更改,则您将想要更新意图,以便它具有正确的总计。
use \Lunar\Stripe\Facades\Stripe; Stripe::syncIntent(\Lunar\Models\Cart $cart);
更新现有的意图
当您想更新支付意图的某些属性时,而不需要重新计算购物车。
请参阅 https://docs.stripe.com/api/payment_intents/update
use \Lunar\Stripe\Facades\Stripe; Stripe::updateIntent(\Lunar\Models\Cart $cart, [ 'shipping' => [/*..*/] ]);
取消现有的意图
如果您需要取消支付意图,则可以这样做。您需要提供一个有效的理由,这些理由可以在 Stripe 文档中找到:https://docs.stripe.com/api/payment_intents/cancel。
Lunar Stripe 包含一个 PHP Enum 来简化此操作
use Lunar\Stripe\Enums\CancellationReason; CancellationReason::ABANDONED; CancellationReason::DUPLICATE; CancellationReason::REQUESTED_BY_CUSTOMER; CancellationReason::FRAUDULENT;
use Lunar\Stripe\Facades\Stripe; use Lunar\Stripe\Enums\CancellationReason; Stripe::cancelIntent(\Lunar\Models\Cart $cart, CancellationReason $reason);
更新 Stripe 上的地址
因此,您无需手动指定所有发货地址字段,可以使用辅助函数来帮您完成。
use \Lunar\Stripe\Facades\Stripe; Stripe::updateShippingAddress(\Lunar\Models\Cart $cart);
费用
检索特定费用
use \Lunar\Stripe\Facades\Stripe; Stripe::getCharge(string $chargeId);
获取支付意图的所有费用
use \Lunar\Stripe\Facades\Stripe; Stripe::getCharges(string $paymentIntentId);
Webhooks
此插件提供了一个可选的webhook,您可以将其添加到Stripe中。您可以在Stripe网站上阅读如何操作的指南https://stripe.com/docs/webhooks/quickstart。
您应该监听的事件是payment_intent.payment_failed
和payment_intent.succeeded
。
webhook的路径将是http:://yoursite.com/stripe/webhook
。
您可以在config/lunar/stripe.php
中自定义webhook的路径。
您还需要将webhook签名密钥添加到services.php
配置文件中。
<?php return [ // ... 'stripe' => [ // ... 'webhooks' => [ 'payment_intent' => '...' ], ], ];
如果您不想使用webhook,或者想手动处理订单,您也可以这样做。
$cart = CartSession::current(); // With a draft order... $draftOrder = $cart->createOrder(); Payments::driver('stripe')->order($draftOrder)->withData([ 'payment_intent' => $draftOrder->meta['payment_intent'], ])->authorize(); // Using just the cart... Payments::driver('stripe')->cart($cart)->withData([ 'payment_intent' => $cart->meta['payment_intent'], ])->authorize();
店面示例
首先,我们需要设置后端API调用以获取或创建意图,这并不是Vue特定的,如果您使用Livewire,它可能有所不同。
use \Lunar\Stripe\Facades\Stripe; Route::post('api/payment-intent', function () { $cart = CartSession::current(); $cartData = CartData::from($cart); if ($paymentIntent = $cartData->meta['payment_intent'] ?? false) { $intent = StripeFacade::fetchIntent($paymentIntent); } else { $intent = StripeFacade::createIntent($cart); } if ($intent->amount != $cart->total->value) { StripeFacade::syncIntent($cart); } return $intent; })->middleware('web');
Vuejs
这仅使用Stripe的支付元素,有关更多信息,请查看Stripe指南。
支付组件
<script setup> const { VITE_STRIPE_PK } = import.meta.env const stripe = Stripe(VITE_STRIPE_PK) const stripeElements = ref({}) const buildForm = async () => { const { data } = await axios.post("api/payment-intent") stripeElements.value = stripe.elements({ clientSecret: data.client_secret, }) const paymentElement = stripeElements.value.create("payment", { layout: "tabs", defaultValues: { billingDetails: { name: `{$billingAddress.value.first_name} {$billingAddress.value?.last_name}`, phone: billingAddress.value?.contact_phone, }, }, fields: { billingDetails: "never", }, }) paymentElement.mount("#payment-element") } onMounted(async () => { await buildForm() }) // The address object can be either passed through as props or via a second API call, but it should likely come from the cart. const submit = async () => { try { const address = {...} const { error } = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements: stripeElements.value, confirmParams: { return_url: 'http://yoursite.com/checkout/complete', payment_method_data: { billing_details: { name: `{$address.first_name} {$address.last_name}`, email: address.contact_email, phone: address.contact_phone, address: { city: address.city, country: address.country.iso2, line1: address.line_one, line2: address.line_two, postal_code: address.postcode, state: address.state, }, }, }, }, }) } catch (e) { } } </script>
<template> <form @submit.prevent="submit"> <div id="payment-element"> <!--Stripe.js injects the Payment Element--> </div> </form> </template>
贡献
欢迎贡献,如果您打算添加功能,请首先提交一个问题,以便我们确定是否应该包含它。
测试
使用MockClient类来模拟Stripe API将返回的响应。