Итак, я создаю веб-приложение, в котором есть магазин с Laravel API и Vue в качестве внешнего SPA.
Я пытался использовать Strip для включения платежей. До сих пор, с помощью документации Stripe, я смог создать источник в веб-интерфейсе. для iDEAL Stripe настоятельно рекомендует использовать веб-зацепки для подтверждения успешности платежа. (Я использую пакет Spatie / Laravel -Stripe-Webhook) Это текущий поток моего веб-приложения:
Оформление заказа. vue:
checkout() {
const sourceData = {
type: 'ideal',
amount: this.cart.total,
currency: 'eur',
owner: {
name: this.name + ' ' + this.last_name,
email: this.email,
},
metadata: {
order: JSON.stringify(order),
total_quantity: this.cart.total_quantity,
},
redirect: {
return_url: 'http://example.test/order-confirmation',
},
}
this.stripe.createSource(this.ideal, sourceData).then(function(result) {
if (result.error) {
console.log(error.message)
this.error = error.message
} else {
stripeSourceHandler(result.source)
}
})
const stripeSourceHandler = source => {
document.location.href = source.redirect.url
}
},
- После заполнение платежного адреса, электронных писем и пр. c. пользователь начинает платеж.
- Пользователь перенаправляется на страницу оплаты iDEAL, где он может авторизовать платеж.
- Источник создан. Stripe отправляет
source.chargeable
webhook:
config / stripe-webhooks. php:
'jobs' => [
'source_chargeable' => \App\Jobs\StripeWebhooks\ProcessPaymentsJob::class,
'charge_succeeded' => \App\Jobs\StripeWebhooks\ChargeSucceededJob::class,
],
ProcessPaymentsJob. php:
public function __construct(WebhookCall $webhookCall)
{
$this->webhookCall = $webhookCall;
}
public function handle()
{
$charge = $this->webhookCall->payload['data']['object'];
\Stripe\Stripe::setApiKey(config('services.stripe.secret'));
$user = '';
if(User::find(Auth::id())) {
$user = $user->name;
} else {
$user = 'a guest';
}
$payment = \Stripe\Charge::create([
'amount' => $charge['amount'],
'currency' => 'eur',
'source' => $charge['id'],
'description' => 'New payment from '. $user,
'metadata' => [
'order' => $charge['metadata']['order'],
'total_quantity' => $charge['metadata']['total_quantity'],
]
]);
}
Пользователь возвращается к
redirect[return_url]
Если все прошло хорошо, Stripe должен отправить обвинение .succeeded webhook:
ChargeSucceededJob. php:
public function __construct(WebhookCall $webhookCall)
{
$this->webhookCall = $webhookCall;
}
public function handle()
{
$charge = $this->webhookCall->payload['data']['object'];
$order = Order::create([
'user_id' => Auth::id() ?? null,
'payment_id' => $charge['id'],
'payment_method' => $charge['payment_method_details']['type'],
'billing_email' => $charge['billing_details']['email'],
'billing_name' => $charge['metadata']['name'],
'billing_last_name' => $charge['metadata']['last_name'],
'billing_address' => $charge['metadata']['address'],
'billing_address_number' => $charge['metadata']['address_num'],
'billing_postal_code' => $charge['metadata']['postal_code'],
'billing_city' => $charge['metadata']['city'],
'billing_phone' => strval($charge['billing_details']['phone']),
'order' => json_decode($charge['metadata']['order']),
'total_quantity' => (int) $charge['metadata']['total_quantity'],
'billing_total' => $charge['amount'],
]);
}
Все идет хорошо. Однако я не знаю, как уведомить клиента (на внешнем интерфейсе) о том, что заказ был выполнен. В документации Stripe они объясняют, как получить Источник на странице подтверждения заказа, но не объясняют, как получить Сбор, потому что именно это определяет, был ли весь заказ выполнен или нет.
Подтверждение заказа. vue:
checkPaymentStatus() {
this.stripe = Stripe(this.stripeKey)
// After some amount of time, we should stop trying to resolve the order synchronously:
const MAX_POLL_COUNT = 10;
let pollCount = 0;
let params = new URLSearchParams(location.search)
const pollForSourceStatus = async () => {
const { source } = await this.stripe.retrieveSource({id: params.get('source'), client_secret: params.get('client_secret')})
if (source.status === 'chargeable') {
// Make a request to your server to charge the Source.
// Depending on the Charge status, show your customer the relevant message.
} else if (source.status === 'pending' && pollCount < MAX_POLL_COUNT) {
// Try again in a second, if the Source is still `pending`:
pollCount += 1;
setTimeout(pollForSourceStatus, 1000);
} else {
// Depending on the Source status, show your customer the relevant message.
}
};
pollForSourceStatus();
}
Как мне go отсюда? Я пытаюсь уведомить интерфейс, когда Charge был успешно выполнен. Мой первоначальный мыслительный процесс состоял в том, чтобы просто вернуть объект Order, как я сделал бы, если бы это был Контроллер, но если я правильно понимаю, задание работает асинхронно, поэтому я не могу вернуть данные. Я также новичок в работе и очередях и прочее, я все еще пытаюсь обернуть им голову.
Другой вариант, о котором я подумал, - это опросить запросы от внешнего интерфейса к внутреннему, чтобы запросить последний заказ, но я понятия не имею, как это будет работать и / или если это хорошее решение.
Любая помощь / советы / полезные ресурсы будут высоко оценены!