I’m trying to create offsite payment extension using this guide build extension but it’s bit confusing, I’ve followed all the steps, but I’m not sure how the authentication works, can someone provide clear steps please?
Hey @hamad.karim - happy to take a look into this. Could you let me know where you’re getting stuck?
Also, are you seeing any specific error messages? And have you been able to successfully receive a payment request from Shopify yet, or are you still in the process of setting up your endpoints?
If you’re using the extension app library that’s set up through those Shopify CLI commands, authentication should be handled automatically as long as your development server is running - just wondering if there are any errors you’re seeing so that we can pinpoint where the issue might be happening.
Hope to hear from you soon!
Hey @Alan_G, Thanks for the prompt response. so here is the issue that I’m facing at the moment.
Guide: Implement authorization code grant manually
While implementing the authorization code flow (step 1), I’m constructing the redirect URL like this:
https://{shop}.myshopify.com/admin/oauth/authorize?client_id={client_id}&scope=write_payment_gateways,write_payment_sessions&redirect_uri={redirect_url}&state={state}
I’m including the required scopes as a comma-separated list, as per the docs.
The redirect works fine, and I receive the authorization code in the callback.
However, when I proceed to step 4 and exchange the code for an access token, the response I get looks like this:
{
“access_token”: “<access_token>”,
“scope”: “”
}
The scope field is completely empty.
Is there a reason the returned token would have an empty scope, even though I’m explicitly passing scopes in the authorization URL?
Any guidance would be appreciated.
Thanks for sharing/clarifying @hamad.karim, that is definitely odd. One reason I can think of where this might result in the empty scope field in the response would be if your payment app hasn’t gone through Shopify’s payment extension review and approval process first (a bit more info here).
Those scopes are technically gated behind additional approvals on our end, so that could be why the scopes aren’t appearing when you add them to your redirect URL.
Right now, payment apps are only enabled by invitation only or for Shopify Plus merchants upon request. If your app is already approved though, let me know and I’m happy to see if we can narrow down what the issue might be.
Hope this helps!
Thanks @Alan_G your first suggestion worked, I had to submit the application for review and release it to apply scope related changes.
I’ve some more queries;
- When Shopify send POST request to our BE(payment_session_url) for creating payment session it doesn’t provide any hmac to authenticate the request, is there any other way to authenticate request? I don’t want to keep the endpoint completely open.
- Is there any way I can embed my checkout page in an iframe? there is an option in app’s toml configuration for admin page to set it embedded or non-embedded but that only applies to Admin page, I can’t find any option to do it for checkout. I see there is an extension type
onsite payment
which is in beta at the moment, but for that I’ll have to build a completely separate checkout extension with forms and stuff.
Hey @hamad.karim - glad this worked for you! Taking a look at your other questions questions here:
In our documentation we do mention using MTLS (more info here), which should allow for a secure connection between our system and your payment app. Unlike HMAC there, we wouldn’t require a token or key in the request payload/header—authentication happens at the TLS handshake level.
For your second question, at the moment, we do only allow on-Shopify payment apps through the beta program (which is invite only). If we do open up the beta though, this would generally be shared either here in the forums or in our changelog (more info here).
Hope this helps!
Let me know if I can clarify anyhting on my end here.
@Alan_G so that means we cannot build embedded or on-shopify payment extension for now? The only option available for payment extension at the moment is non-embedded offsite payment?
Hi @hamad.karim, that’s correct. Right now, on-Shopify payment apps are only available to be created by partners via invite-only beta (or for Shopify Plus shops on a per-basis approval).
Hope this helps clarify things, let me know if I can assist with anything else
Hi @Alan_G, thanks for the clarification. I’ll proceed with offsite payment for now.
In the Shopify admin, merchants can toggle card brands (available payment methods) for a payment extension. How can I fetch the accepted payment methods settings on my backend? Is there a webhook or query to retrieve this information? For example, if a merchant disables Visa, how will my backend be notified so I can update my offsite payment page accordingly?
Hey again @hamad.karim, hopefully I’m understanding correctly, but those payment type toggles that are available in the admin are associated with the Shopify Payments gateway and wouldn’t necessarily reflect what’s available on other payment gateways:
At the moment there’s not a way to query these directly through the Payment App API, but I’ll definitely put through a feature request for you so that we can look into making it easier for payment apps to reflect the native Shopify Payments settings that merchants set. I’ll ge that set up on my end here right away!
@Alan_G you’re correct, I was referring to these settings. There should be a webhook to notify apps when merchants update payment methods (e.g., disabling Visa) or a query to fetch these settings to keep payment apps in sync. Alternatively, enabling payment apps to hide these settings in the admin panel could also prevent confusion.
Like in our case we’re handling this functionality on our platform, so it would be better if we could just hide these setting from Shopify admin and let the merchants update this from our own platform.
Please let me know when you have update on this, I’ll update my app accordingly.
Thanks.
Thanks @hamad.karim, I appreciate the extra context here.
I still can’t guarantee anything at this time, but I’ll add the extra info you shared here to the feature request I’ve logged on my end. Feel free to ping me here any time and I can take a look at the progress.
As we chatted about, I still can’t guarantee specific updates or timelines, but I’m happy to keep an eye on this.
Hi @Alan_G, I have another question regarding our app’s onboarding flow. When our app calls the paymentsAppConfigure mutation, Shopify should mark the extension as ready for activation. This was working fine initially, but over the last two days, I’ve noticed an issue. After calling paymentsAppConfigure and redirecting the merchant to the extension settings page in Shopify, it shows the installation page again, suggesting the previous installation failed. However, I confirmed the mutation returns a 200 response without any errors on our end. To add to the confusion, when I logged in with my staff account, the extension appeared installed in the store, but the owner account still saw the installation page even after multiple page refreshes. Could you help clarify what might be causing this behavior?
Hey @hamad.karim - thanks for reaching back out - that does sound odd, happy to look into this further. I think my next step here will be to reach out to our product team for you, but could you let me know if when they’re redirected to the installation page, if they then refresh the page, are they still on the installation page or does it take them to a different landing page in the admin?
If you’re able to share a screen recording of the issue, that would be super helpful as well if it’s replicable. My thinking is that it may have been a browser caching issue, but if it’s happening consistently that would point to a possible issue on our end for sure.
Linking my findings here too:
Hi @Alan_G and @mropanen ,
Thanks for your help with the recent issue. It was caused by strict caching on the Shopify Admin dashboard. Clearing the cache and cookies resolved it for me.
We’ve also successfully pushed the first version of our payment extension—big thanks to @Alan_G for the ongoing support!
I have a follow-up question about refund processing, which I’ve been discussing with Shopify support, but they directed me to the community for help. The standard refund flow through the Shopify Admin dashboard (order page > refund_session_url) works fine. However, We provide an additional functionality to our merchants to log in to our platform to view their transactions, and initiate refunds directly from our platform without accessing the Shopify Admin dashboard. To sync these refunds on Shopify’s order details page, we use the createRefund
mutation, which requires the orderID. Unfortunately, Shopify’s payment payload doesn’t include the orderID. To retrieve the orderID using the payment ID, we would need write_orders
and read_all_orders
scopes, but Shopify rejected our request for these, as payment apps are restricted to payment-related scopes only.
Could you suggest a workaround to initiate and sync refunds from our platform to Shopify’s order details page without access to the orderID? Any advice or alternative solutions would be greatly appreciated.
Hey @hamad.karim - glad to hear that your payment app is live! When it comes to refunds being actioned outside of the Shopify Admin, that is currently a limitation of the platform (there’s a bit more info here).
At the moment, we do only allow for merchants to action refunds from inside the Shopify Admin itself as it relates to the options a payment method can offer ( the createRefund
mutation can be used by non-payment apps for order management, etc). When it comes to retrieving order IDs themselves, this is also something that only non-payment apps can do (payment apps are only allowed to use our Payment APIs/necessary webhooks at the moment).
I’m happy to put through a feature request though on my end if you’re open to sharing a use-case, feel free to ping me here and I’m happy to take a closer look for sure. Hope this helps a little bit.