I developed a web-app in PHP (old-school, no framework). For a while now I'm struggling with onboarding merchants via Mollie Connect and subsequently creating payments on behalf of those onboarded merchants. Mainly oAuth2 seems to be bugging me. My skills level is just not good enough. Anyone have the time and skills to help me out this week or the next?
#Looking for help on implementing Mollie Connect oAuth.
1 messages Β· Page 1 of 1 (latest)
Sure, I'll try my best! Can you share a bit more about where you stand now, and what blockers you hit? oAuth2 can be a bit tricky, are you using any libraries for this, or did you implement it from scratch?
Hi Florian,
I implemented it from scratch, using Mollie's package that I implemented with Composer into my application.
I managed to onboard a merchant, so that I received the merchants profile Id ('prf_..') and a access token 'access_..). However, I guess I need more than that to be able to start a new Payment on their behalf. And that's where I got stuck. I had a video-meet with your colleagues at Mollie last week, but I have to admit I do not get the picture..
Looking for help on implementing Mollie Connect oAuth.
Well that sounds like a lot already accomplished. What happens when you try to create a payment with the access token as authorization?
I did not manage to create a payment with that access token. It turned out the payment was made under my own account, not under the account of the merchant. So any payments were landing on my Mollie account, not on the merchant's account.
According to the Mollie documentation I need to acquire fresh authorisation tokens when I want to create a new payment on behalf of that merchant. And that requires oAuth. And that's what I do not grasp.
So all I have been able to do is 'onboard' the merchant. That needs only be done once, I'm sure. The rest is, including oAuth calls to get fresh tokens I need the help with.
Interesting! Can you share the organization IDs of both your account and the merchant's that is connected? Just the numeric IDs are sufficient.
I just want to verify really quick that everything is set up correctly
My account ID: 1730811
Merchant's ID: 16158768
Okay, the setup looks fine - your app is registered and the target merchant has authorized it to access their account, also with the right permissions.
During the authorization you should have received an auth code. That you can use to request an access token. An access token is only valid for an hour, so you need to do that a lot. The access token then can be used to interact with the normal Mollie API endpoints on the merchant's behalf.
The OAuth2 endpoints behave a little different than the others on Mollie's API, so you need to pay a bit of attention as to when you need which type of authorization (eg. for the authorize and tokens endpoint you need your Client ID and Client Secret).
Did you use this package https://github.com/mollie/oauth2-mollie-php when you mentioned "Mollie's package" in your above message?
Hi Florian,
Yes, I installed the mollie oauth2 php package.
What I received during the authorization was a Mollie access token ('access...') and a profile ID ('pfl_..'), not a auth-token. Or at least, I did not store it.
So since I do not have a auth-token, do I need to retry the onboarding process with the merchant?
If the App is authorized (which it is), you shouldn't have to redo onboarding. Simply re-run the authorization, and you should receive an AccessToken object containing an access token and a refresh token.
Once you have an accessToken, you can also validate which Organization it belongs to: $provider->getResourceOwner($accessToken)
Thank you Florian,
I will give it a try asap and will let you know. You've been very helpful and patient with me. π
..ok, so I now have an accessToken and a refresh token. Do I need to save both in my database for when I want to create a payment, or do I only need the refresh token?
And what about the authorization code? No need to save that in my database?
The Auth code is only for the initial authorization flow. Once you received your first AccessToken object, it will contain a refreshToken that you should store securely. You should also store the accessToken and its expiry timestamp.
Whenever you want to do an API Call on behalf of a certain merchant, you'd first look if you have an accessToken stored that is not yet expired. If you have that, use it. If your accessToken is expired, you should use the refreshToken to fetch a new one (https://github.com/mollie/oauth2-mollie-php#refreshing-a-token). Store the new accessToken and expiry, and throw away the old one. Rinse and repeat π
Noob q: how do I get the refreshToken from the AccessToken object in PHP..? Since AccessToken is a object containing protected data. Is there a getter in League\OAuth2 ?
Yup, the AccessTokenInterface defines a getRefreshToken getter.
Lovely.. another step completed. Gone out shopping for pie ingredients.. π
Ok, so I'm back at it.. Here's what I don't grasp:
I now have the merchant's refreshToken and am able to get a fresh accessToken from that. So the next step is how to create a payment on behalf of the merchant.
In the docs there is this page on creating a payment: https://docs.mollie.com/reference/v2/payments-api/create-payment#pfp-params
But if I create a payment that way, the payment is not made on behalf of the merchant. The money paid is ending up in MY Mollie account, not in the Merchant's account where it should be going. So what am I doing wrong or what am I missing? How do I create the payment on behalf of the merchant? Attached is an example of how I create the payment.
The first thing I spot is that you do $mollie->setApiKey(MOLLIE_LIVE_API_KEY); which sets the API Key used to probably your Live API Key. This is not what you want in this instance.
You want to use setAccessToken and put as an argument the valid Access Token that you grabbed with your Refresh Token previously. In your payment you then have to make the profileId explicit (you do that already), and (if desired) set testmode to true in the payload so you stay in test mode for the time being.
You can also take a look at the examples provided here https://github.com/mollie/mollie-api-php/blob/master/examples/initialize_with_oauth.php and here https://github.com/mollie/mollie-api-php/blob/master/examples/payments/create-payment-oauth.php
Wondering if this was helpful π
Still working on it, Florian. It is taking me more time than hoped, all in all. Two steps forward, one step back..
All right, just making sure you got everything you need from my end, as I lose track of Discord Threads sometimes
Ok, so I now managed to create a payment in testmode. Seems to work ok (I can make the test-payment as if I am the customer), although I had to hack some code to get it working.
But when my webhook is called by Mollie, there's an error saying 'No payment exists with token tr_WGxCdaE88H'. But I am sure the token is the one with which the testpayment was made.
Any thoughts?
I initialized Mollie in my webhook script with my own test-api-key:
$mollie = new \Mollie\Api\MollieApiClient();
$mollie->setApiKey(MOLLIE_TEST_API_KEY);
Error msg in my log:
mod_fcgid: stderr: PHP Fatal error: Uncaught Mollie\Api\Exceptions\ApiException: [2022-12-15T09:51:15+0100] Error executing API call (404: Not Found): No payment exists with token tr_WGxCdaxxxx.. Documentation: https://docs.mollie.com/overview/handling-errors in /vendor/mollie/mollie-api-php/src/Exceptions/ApiException.php:114
Hi @analog mist , you're essentially trying to interact with Mollie's API on behalf of the merchant. You'll need to use the merchant's access token with ->setAccessToken($accessToken) instead of your api key with setApiKey. The mechanics of retrieving are the same as for creating a payment of behalf of the merchant.
But what if two payments for 2 different merchants are performed at the same time? How would webhook know which merchant.. oh.. wait.. I can save it in my database together with the transaction id..
Gracias π
Almost there..
Mollie webhook is called successfully after a test-payment, but then:
mod_fcgid: stderr: PHP Fatal error: Uncaught Mollie\Api\Exceptions\ApiException: [2022-12-15T13:03:47+0100] Error executing API call (404: Not Found): Payment tr_xnsNcfrxxx exists, but the wrong mode is used. Try switching live / test API keys
I made the payment in 'testmode'. And I used the merchant's accessToken to interact with the Mollie API.
But how do I set this to testmode:
$payment = $mollie->payments->get($_POST["id"]);
Documentation does not help me.
I'm not sure if it's okay to post a similar issue here, or start a new thread.
I need help with this setup but from a Rails app.
I'm getting the auth code. but I'm unable to make a successful request to retrieve the access token.
@blazing flare , Any way you can help?
I'm simply making direct url requests without using the gem, as I can see how to make the same with the gem. i.e. Mollie-Api-Ruby
Hey @burnt nova! I would suggest to start a new thread for better visibility/community help π€ cc @blazing flare
$mollie->payments->get($_POST['id'], ["testmode" => true]); should do the trick. You should of course only add that conditionally, when you indeed want test mode.
@burnt nova agreed with Ksenia, could you start a new Thread and link me in it, sharing the portion of the code you're struggling with?
ππ
@blazing flare White smoke!
I finally got things up and running. There are 2 hacks I had to use though.
#1: In order to retrieve the merchant's profileId I was supposed to use this:
$profiles = $mollie->profiles->page();
$profile = reset($profiles);
$profileId = $profile->id;
However that always resulted in a empty value. So what I did was store the profileId in my database when I initially connected the merchant to my app.
#2: When creating a new Payment, the method $payment->getCheckoutUrl() did not return anything. Instead I used
$checkoutUrl = $payment->_links->checkout->href;
to get the checkout url.
Wondering if these 2 issues could be related to version issues in the Mollie / League / Guzzlehttp classes, though I updated all via Composer..? Any thoughts?
But most of all: thank you very much for your help and your patience with me. π
Hm, those two are interesting indeed - maybe @naive hound has an idea here.
You're most welcome, happy you got it running now π
For obtaining the profileId: you typically fetch all and then have the merchant select which one to use. Have you tried omitting reset() here and use $profiles[0] instead?
About the $payment->getCheckoutUrl() issue: when that occurs, can you var_dump (or dd in Laravel) the payment and share it?