thephpleague / omnipay-sagepay

Sage Pay driver for the Omnipay PHP payment processing library
MIT License
54 stars 78 forks source link

VendorTxCode refund param being unset on refund()->send() #202

Closed JJonesFK closed 3 months ago

JJonesFK commented 3 months ago

Heyo,

Im having an issues where my VendorTxCode is being emptyed/removed on the send() from a refund.

Here the code im using

    /**
     * _processSagePayRefund
     *
     * @param Request $request
     * @param Order   $order
     * @param User | false | null    $user
     *
     * @return RedirectResponse
     */
    private function _processSagePayRefund(Request $request, Order &$order, User | false | null $user)
    // : RedirectResponse
    {
        $sagepay_vendor = config('services.sagepay.vendor');
        $sagepay_sandbox = config('services.sagepay.sandbox');

        // Initialize the Sagepay payment gateway instants.
        $gateway = Omnipay::create('SagePay\Server');
        $gateway->setVendor($sagepay_vendor);
        $gateway->setTestMode($sagepay_sandbox);

        $vpsTaxId = $order->VPSTxId;
        $reference = json_decode($vpsTaxId, true);
        // Get the refund amount from order.
        $refundAmount = $order->total;
        // In case user has specified an amount.
        if ($request->has('amount') && $refundAmount >= $request->input('amount')) {
            // Set that amount.
            $refundAmount = $request->input('amount');
        }
        $vendorTxCode = "REF-" . $refundAmount . "-" . $order->ref_id;

        $params = [
            // Transaction type. Should be in Capital letters.
            'TxType' => "REFUND",
            'VendorTxCode' => $vendorTxCode,
            'amount' => $refundAmount,
            'currency' => $order->currency,
            'description' => substr('Refund for Order #' . $reference['VPSTxId'], 0, 90),
            'VPSTxId' => $reference,
            'transactionReference' => json_encode($reference),
            'TxAuthNo' => $reference['TxAuthNo'] ?? null,
        ];
        $params['transactionId'] = $vendorTxCode;
        $params['vendor'] = config('services.sagepay.vendor');
        $params['VPSTxId'] = json_encode($reference);

        try {
            $response = $gateway->refund($params)->send();

        } catch (\Exception $e) {
            Alert::warning('Error', "Refund failed: " . $e->getMessage());
            \Log::info($order->id . " _processSagePayRefund - Failed to issue a refund: " . $e->getMessage());
            return back()->with('error', "Refund failed: " . $e->getMessage());
        }
        // Check if refund was successful.
        if ($response->isSuccessful()) {
            // Get the ID of the refund transaction reference.
            $refundTransactionId = $response->getTransactionReference();

            \Log::info($order->id . " _processSagePayRefund - isSuccessful -" . $refundTransactionId);
            // Update status on order record.
            $order->update(['order_status' => Order::REFUNDED]);
            // Save the refund transaction reference.
            $order->transactions()->create([
                'transaction_status' => OrderTransaction::REFUNDED,
                'transaction_number' => $refundTransactionId,
                'payment_result' => "success",
            ]);
            // Return success to user.
            return back()->with('success', "Refund successful. Transaction ID: " . $refundTransactionId);
        } else {
            // Refund failed return back to user.
            \Log::info($order->id . " _processSagePayRefund - isSuccessful - failed " . $response->getMessage());
            return back()->with('error', "Refund failed: " . $response->getMessage());
        }
    }

Here a screen shot of the params array and the $gateway->refund($params)->send() in a dd()

image

Im completely lost on what to do here. I get a 3009 : Missing VendorTxCode from the sagepay server response

jamieburchell commented 3 months ago

@JJonesFK

Looking at this again, I can see that the value for VendorTxCode (as presented to Opayo) is derived from the transactionId parameter.

TxType is not required, it's set by the refund() method. vendorTxCode is not required.

Try this as your params array:

$params = [
   'transactionReference' => $order->VPSTxId,
   'amount' => $refundAmount,
   'currency' => $order->currency,
   'description' => substr('Refund for Order #' . $reference['VPSTxId'], 0, 90),
   'transactionId' => $vendorTxCode
];
JJonesFK commented 3 months ago

Thank you!

I didnt realise i need the transactionId.

image