Skip to content

Commit

Permalink
Enable stripecheckout refund
Browse files Browse the repository at this point in the history
  • Loading branch information
philipxyc committed Sep 16, 2022
1 parent 01b6e77 commit 190c294
Showing 1 changed file with 63 additions and 11 deletions.
74 changes: 63 additions & 11 deletions payments/StripeCheckout.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public function processSuccessUrl($params)
if (!$paymentMethod || $paymentMethod->getGatewayClass() != static::class)
throw new ApplicationException('No valid payment method found');

$order->logPaymentAttempt('Payment successful', 1, [], $paymentMethod, true);
// Don't have detailed payment info, not refundable.
$order->logPaymentAttempt('Payment successful (not final)', 1, [], $paymentMethod, true);
$order->updateOrderStatus($paymentMethod->order_status, ['notify' => false]);
$order->markAsPaymentProcessed();

Expand Down Expand Up @@ -151,6 +152,58 @@ protected function createGateway()
return $stripeClient;
}

protected function getPaymentRefundFields($order, $data)
{
$fields = [];

$eventResult = $this->fireSystemEvent('payregister.stripe.extendRefundFields', [$fields, $order, $data], false);
if (is_array($eventResult))
$fields = array_merge($fields, ...$eventResult);

return $fields;
}

public function processRefundForm($data, $order, $paymentLog)
{
if (!is_null($paymentLog->refunded_at) || !is_array($paymentLog->response))
throw new ApplicationException('Nothing to refund');

if (!array_get($paymentLog->response, 'status') === 'succeeded'
|| !array_get($paymentLog->response, 'object') === 'payment_intent'
) throw new ApplicationException('No charge to refund');

$paymentIntentId = array_get($paymentLog->response, 'payment_intent');
$refundAmount = array_get($data, 'refund_type') == 'full'
? $order->order_total : array_get($data, 'refund_amount');

if ($refundAmount > $order->order_total)
throw new ApplicationException('Refund amount should be be less than total');

try {
$gateway = $this->createGateway();
$fields = $this->getPaymentRefundFields($order, $data);
$response = $gateway->refunds->create(array_merge($fields, [
'payment_intent' => $paymentIntentId,
'amount' => number_format($refundAmount, 2, '', ''),
]));

if ($response->status === 'failed')
throw new Exception('Refund failed');

$message = sprintf('Payment intent %s refunded successfully -> (%s: %s)',
$paymentIntentId,
currency_format($refundAmount),
array_get($response->toArray(), 'refunds.data.0.id')
);

$order->logPaymentAttempt($message, 1, $fields, $response->toArray());
$paymentLog->markAsRefundProcessed();
}
catch (Exception $e) {
$order->logPaymentAttempt('Refund failed -> '.$response->getMessage(), 0, $fields, $response->toArray());
}
}

protected function getPaymentFormFields($order, $data = [])
{
$cancelUrl = $this->makeEntryPointUrl('stripe_checkout_cancel_url').'/'.$order->hash;
Expand Down Expand Up @@ -179,7 +232,7 @@ protected function getPaymentFormFields($order, $data = [])
],
];


// Share the email field in our form to Stripe checkout session,
// so customers don't need to enter twice
if (!is_null(array_get($data, 'email'))) {
Expand Down Expand Up @@ -218,16 +271,15 @@ public function processWebhookUrl()
protected function webhookHandleCheckoutSessionCompleted($payload)
{
if ($order = Orders_model::find($payload['data']['object']['metadata']['order_id'])) {
if (!$order->isPaymentProcessed()) {
if ($payload['data']['object']['status'] === 'requires_capture') {
$order->logPaymentAttempt('Payment authorized', 1, [], $payload['data']['object']);
} else {
$order->logPaymentAttempt('Payment successful', 1, [], $payload['data']['object'], true);
}

$order->updateOrderStatus($this->model->order_status, ['notify' => false]);
$order->markAsPaymentProcessed();
if ($payload['data']['object']['status'] === 'requires_capture') {
$order->logPaymentAttempt('Payment authorized', 1, [], $payload['data']['object']);
} else {
// Have detailed payment info, refundable.
$order->logPaymentAttempt('Payment confirmed (Finalized, Refundable)', 1, [], $payload['data']['object'], true);
}

$order->updateOrderStatus($this->model->order_status, ['notify' => false]);
$order->markAsPaymentProcessed();
}
}
}

0 comments on commit 190c294

Please sign in to comment.