Merx – Plugin to create online shops with Kirby 3

, ,

Hello. I am experiencing a weird problem with shipping calculations.

I have a checkout page, where the shipping method and cost is calculated (by calling a ‘set-shipping’ route with fetch) based on the selected shipping country. Upon visiting this checkout page, a default shipping product is added for the default country.

I am adding this default shipping product with this code:

// controllers/checkout.php
...
$cart = merx()->cart();
// I first remove all shipping products, because selecting another country adds a shipping product on top of the default one.
removeAllShippingMethods($cart); 
  
$cart->add([
  'id' => $defaultShippingMethod->id(),
  'type' => 'shipping',
  'price' => cartSumAboveFreeShipping($defaultShippingMethod) ? 0 : (float) $defaultShippingMethod->price()->value()
]);
...

Everything works so far. The problem presents itself when the payment is performed. No matter which shipping method is selected, the default shipping product is always passed to the payment method (Stripe). Curiously, the correct shipping method (the one selected by the user) is registered on the order page created by Merx.

Ι updated this post many times (10 so far!) to not flood the topic. Sorry!

I found out that by adding the shipping product via fetch, the product seems to be added on the page, but is not passed to payment. Only if I refresh the checkout page this product is actually added.

My shipping route:

[
  'pattern' => 'shop-api/set-shipping',
  'method' => 'POST',
  'action' => function() {
    try {
      $data = kirby()->request()->data();
      $method = kirby()->page($data['method']);
      
      $method_data = [
        'name' => $method->title()->value(),
        'from' => $method->from()->value(),
        'to' => $method->to()->value(),
        'price' => cartSumAboveFreeShipping($method) ? 0 : formatCurrency($method->price()->value())
      ];
      
      $cart = merx()->cart();

      removeAllShipping($cart);

      $cart->add([
        'id' => $method->id(),
        'type' => 'shipping',
        'price' => cartSumAboveFreeShipping($method) ? 0 : (float) $method->price()->value()
      ]);
        
      return [
        'status' => 200,
        'method' => $method_data,
        'itemsBuildTime' => allItemsBuildTime(),
        'cart' => [
          'subtotal' => formatCurrency($cart->filterBy('type', 'product')->getSum()),
          'total' => formatCurrency($cart->getSum()),
        ]
      ];
    } catch (Kirby\Exception\Exception $ex) {
      return $ex->toArray();
    }
  },
],

Ο, I solved it. I was always using the same StripePaymentIntent that I set in the checkout controller. It needed to be created after all the peoduct changes.

Hi Everyone - I ran into some trouble that I somehow can not really pinpoint after experimenting with MERX the last couple of days.

The shop I’m creating is basically up and running, thanks to the babyreport example. Paypal is working just fine, but whenever I try to use the stripepaymentintent I get sort of a weird json error.

Does anyone have a hint for me?

@tobiasfabian or anyone else :slight_smile: I have an issue with Stripe. During Stripe’s redirect to the success page, Stripe shows a button “Return to Merchant” If the user doesn’t wait for the automatic redirect and clicks the button (understandable), the user is redirected to the cart/checkout with an error saying the payment couldn’t be finished. The user is still charged, but Stripe doesn’t register it as a charge and will refund it in 1 or 2 days (they say). How can I make sure this “Return to Merchant” button is not visible or doesn’t result in an error? I really hope I can solve this issue fast. If it is any help, I can give access to the code on GitHub.

Kind regards,
Bart

Also the same link for the ‘button’ is used for the automatic redirect. Both creating complete different results.

Can you show us your shop-api/get-client-secret route? There seems to be a problem with this.

Did you set the ww.merx.stripe.test.publishable_key and ww.merx.stripe.test.secret_key ?

What payment method do you use?

I think I found the issue (not a solution). The automatic redirect (on Stripe) triggers the link and creates the orderpage. The manual click by the user on the button (on Stripe) also triggers the exact same link and also tries to create the orderpage -> error.

In this situation the orderpage is created, emails are send, but the user gets an error. When I discovered the issue even the orderpage and emails weren’t created. So this part I don’t understand.

Edit: When I disable the automatic redirect on Stripe by disabling JavaScript in my browser and click the “Return to Merchant” button, all works as intended.

I added iDeal as a gateway

Gateways::$gateways['ideal'] = [
'initializePayment' => function (OrderPage $virtualOrderPage): OrderPage
{
    $data = [
    ];
    $source = Payment::createStripeSource($virtualOrderPage->cart()->getSum(), 'ideal', $data);
    $virtualOrderPage->content()->update([
        'redirect' => $source->redirect->url,
    ]);
    return $virtualOrderPage;
},
'completePayment' => function (OrderPage $virtualOrderPage, array $data): OrderPage
{
    return completeStripePayment($virtualOrderPage, $data);
},

];

Yes, the keys are set and they seem to be the right ones.
My rout looks like this:


   [
      'pattern' => 'shop-api/get-client-secret',
      'action' => function() {
         $merx = merx();
         $cart = $merx->cart();
         $paymentIntent = $cart->getStripePaymentIntent();
         kirby()->session()->set('ww.site.paymentIntentId', $paymentIntent->id);
         return [
          'clientSecret' => $paymentIntent->client_secret,
         ];
      },
    ],

And here is http://dietz.ee/ a shop made with Kirby, MERX and love where…

every product does cost the same like the identical real life product

… I coded it, it was designed by Mark Bohle.

It has some amazing prints, for your christmas presents.

Thanks @tobiasfabian for your help.

4 Likes

@tobiasfabian An update. I believe the issue of the “Return to Merchant” resulting in an error and not charging the customer are two completely unrelated issues.

Not charging customers could be due to an issue on iDeal’s side. Without changing anything, this issue is ‘disappearing’. Also I know now some other websites had similar issues this week.

The “Return to Merchant” button still creates an order and an error because completePayment() is triggered twice (automatic redirect and manual click). The first time creates the orderPage, the manual click creates an exception.

I solved the “Return to Merchant” by setting the orderPage url in the session:

In the success controller:

<?php

try {
	$orderPage = merx()->completePayment($_GET);
	kirby()->session()->set('theknitwitstable.orderPageURL', $orderPage->url());
	go($orderPage->url());
} catch (Exception $ex) {
	if (kirby()->session()->get('theknitwitstable.orderPageURL') !== null) {
		go(kirby()->session()->get('theknitwitstable.orderPageURL'));
	} else {
		merx()->setMessage($ex->getMessage());
		go(option('ww.merx.checkoutPage'));
	}
}

And in the order controller

if (kirby()->session()->get('theknitwitstable.orderPageURL') !== null) {
    kirby()->session()->remove('theknitwitstable.orderPageURL');
}

I’m glad you solved your issue.
Unfortunately I can’t help with custom payment gateways at the moment.

What’s the response of https://faberatelier.ch/shop-api/get-client-secret when you enable debug?

You are getting a Stripe error on your checkout page maybe it’s related somehow.

When I open: https://faberatelier.ch/shop-api/get-client-secret, I get this response:

But my keys should be set in my config file like this:

This seems to be all correct. You could double check the output of option('ww.merx.stripe.live.publishable_key').

is ww.merx.stripe.live.secrete_key a typo?

1 Like

Hi all,
I have updated my Kirby version (from 3.3.4 to 3.4.5) and I’m using this checkout controller: https://github.com/wagnerwagner/merx-examples/blob/plainkit/site/controllers/checkout.php

Everything works fine with 3.3.4. With 3.4.5 the routing gets stuck. It completes the order and the order page even gets created. But no redirect to the order page is happening and no error is thrown. But what’s most interesting is, that the whole page freezes. A reload, even of the root page is never fulfilled. The page just doesn’t want to load, but also no error is given (neither debug, xhr or console, etc.) If I delete the session or cookie everything is back to normal, until I complete another order.

Has anyone any ideas?

@tobiasfabian I need to buy a Merx license, but neither Klarna works (I can’t select any other country than Germany, but my client is in Austria) nor Direct Debit (see screenshot).

I’ve fixed this. SEPA should now be working.

1 Like