duncanmcclean / simple-commerce

A simple, yet powerful e-commerce addon for Statamic.
https://statamic.com/addons/duncanmcclean/simple-commerce
Other
146 stars 40 forks source link

Can't refund Stripe payments? #1071

Closed sbrow closed 4 months ago

sbrow commented 5 months ago

Description

I do not appear to have the option to refund Stripe payments. I think this might have to do with DuncanMcClean\SimpleCommerce\Listeners\TidyTemporaryGatewayData removing the Stripe data after the payment is completed, as once the Stripe webhook hits my site, I lose all stripe data from my Order entry.

I even tried saving the stripe data and adding it back to the model after the webhook fired, but to no avail. I believe this issue is related to #1026, as The payment gateway field shows "Unknown", which makes sense since there's no gateway data.

I attempted a similar fix to #1029, adding the following code to the StripeGateway, but it didn't help.

<?php

namespace DuncanMcClean\SimpleCommerce\Gateways\Builtin;

// ...

class Stripe Gateway extends BaseGateway implements Gateway
{
    // ...

    public function webhook(Request $request)
    {
        $this->setUpWithStripe();

        $payload = json_decode($request->getContent(), true);
        $method = 'handle'.Str::studly(str_replace('.', '_', $payload['type']));

        $data = $payload['data']['object'];

        if ($method === 'handlePaymentIntentSucceeded') {
            $order = Order::find($data['metadata']['order_id']);

            // Added these two lines
            $order->gatewayData(data: $data);
            $order->save();

            $this->markOrderAsPaid($order);

            return new Response('Webhook handled', 200);
        }

        // ...
    }

    // ...
}

Is this intentional? Was it removed at some point?

Thank you for your time.

Steps to reproduce

  1. Configure Stripe as your gateway.
  2. Make an order with stripe in test mode
  3. Select the order in the backend- there is no "Refund" option
  4. Check the order yaml, the stripe key has been deleted.

Environment

Environment Application Name: <Redacted> Laravel Version: 10.47.0 PHP Version: 8.2.13 Composer Version: 2.6.5 Environment: local Debug Mode: ENABLED URL: <Redacted>.ngrok-free.dev Maintenance Mode: OFF

Cache Config: NOT CACHED Events: NOT CACHED Routes: NOT CACHED Views: CACHED

Drivers Broadcasting: log Cache: statamic Database: mysql Logs: stack / single Mail: smtp Queue: sync Session: file

Simple Commerce Currencies: USD Gateways: Stripe Repository: Customer: DuncanMcClean\SimpleCommerce\Customers\UserCustomerRepository Repository: Order: DuncanMcClean\SimpleCommerce\Orders\EntryOrderRepository Repository: Product: DuncanMcClean\SimpleCommerce\Products\EntryProductRepository Shipping Methods: Free Shipping Tax Engine: DuncanMcClean\SimpleCommerce\Tax\Standard\TaxEngine

Sentry Enabled: YES Environment: local Laravel SDK Version: 4.5.1 PHP SDK Version: 4.7.0 Release: NOT SET Sample Rate Errors: 100% Sample Rate Performance Monitoring: 100% Sample Rate Profiling: NOT SET Send Default PII: DISABLED

Statamic Addons: 8 Antlers: runtime Sites: 1 Stache Watcher: Enabled Static Caching: Disabled Version: 4.57.2 PRO

Statamic Addons arthurperton/wordpress-users: 1.1.1 duncanmcclean/guest-entries: 3.2.0 duncanmcclean/simple-commerce: 6.3.0 <Redacted>/sc-checkout: dev-master <Redacted>/sc-subscriptions: dev-master sbrow/banner: dev-master statamic/seo-pro: 5.4.4 stefangalescu/statamic-heroicons: 2.1.1

sbrow commented 5 months ago

I think I was able to solve this by tweaking my first attempt:

$order->gatewayData(data: array_merge([
    'payment_intent' => $data['id'],
], $data));
$order->save();
github-actions[bot] commented 4 months ago

Released as part of v6.3.1.

github-actions[bot] commented 4 months ago

Released as part of v7.0.1.

duncanmcclean commented 4 months ago

Thanks for reporting - this should be fixed now for future orders.

The stripe key in the order data is temporary, when the order is marked as paid, it should now save the ID of the payment intent under gateway->data.