Edenred Direct Payment Services
Integration guide
Overview
Edenred Payment Services allows a partner platform to initiate a payment using an ER payment means (meal card...) after authentication of end user (cardholder). The aim of this document is to describe the integration of Edenred Connect (authentication platform) and Edenred Payment APIs.
Edenred Connect environments
The environment base address is called {{xp-identityserver-url}} OR {{authentication-url}} in script samples.
Environment | Base address | |
---|---|---|
Sandbox | https://sso.sbx.edenred.io | |
Production | Available on request |
Payment APIs environments
The environment base address is called {{payment-url}} OR {{xp-fooddelivery-url}} in script samples.
Environment | Base address | |
---|---|---|
Sandbox | https://directpayment.stg.eu.edenred.io/v2 | |
Production | Available on request |
Authentication Process
1 / Edenred Connect
Edenred Connect is an identity provider that implements OpenID Connect and OAuth 2.0.
2/ Authorization Code Flow
Authorization Code flow involves a two-step process, where the user validates himself against the authorization server by providing his own identity credentials. Then , Connect validates the user credentials and provides with an Authorization Code.
The authorization code flow offers a few benefits over the other grant types. When the user authorizes the application, they are redirected back to the application with a temporary code in the URL. The application exchanges that code for the access token. When the application makes the request for the access token, that request can be authenticated with the client secret, which reduces the risk of an attacker intercepting the authorization code and using it themselves. This also means the access token is never visible to the user or their browser, so it is the most secure way to pass the token back to the application, reducing the risk of the token leaking to someone else.
3/ Requirement
The prerequisite of this flow is that the client application must be registed in Connect to obtain a clientId and a clientSecret which are needed during the token exchange requests.
The client should be configured with:
- allowedGrantTypes: should contains authorization_code in order to use Authorization Code Flow. Otherwise, the authorization fail.
- allowedScopes: a list of scopes to be used while authorization, if the requested scope in not mentioned in this list, the authorization fails.
- redirectUris : lists of accepted redirects Urls , if the requested redirecturl is not mentioned in this list, the authentication fails.
- postLogoutRedirectUris : lists of accepted Urls for logout.
Note : Assert that the client used by you application has the right configuration to use Authorization Code Flow.
4/ Initiating authentication: Login
A/ Authorize Endpoint Request
The authorize endpoint can be used to request tokens or authorization codes via the browser. This process typically involves authentication of the end-user and optionally consent.
GET /connect/authorize? HTTP 1.1
response_type={{authentication_response_type}}
&client_id={{authentication_clientId}}
&scope={{authentication-scopes}}
&redirect_uri={{authentication-redirectUri}}
&acr_values={{authentication-tenant}}
&ui_locales={{authentication_ui_locales}}
&state={{authentication-state}}
&nonce={{authentication-nonce}}
- response_type : for Authorization Code Flow the value of {{authentication_response_type}} should be *code. The client should have "authorization_code" in the list allowedGrantTypes.
- client_id *: unique idenitifier the client.
- scopes *: Scope is a mechanism in OAuth 2.0 to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted. . The client should have the requested scope in its allowedScopes.
- openid
- offline_access : offline_access scope is required for requesting refresh token.Other scopes or Api Ressources can be used like: profile, phone, address ...
- redirect_uri *: The uri , where connect will redirect the code, must exactly match one of the allowed redirects URIs for that client.
- arc_values * : allows passing in additional authentication related information, like tenant. acr_values: tenant:name_of_tenant
- ui_locales *: a hint about the desired display language of the login UI.
- state : echos back the state value on the token response, this is for round tripping state between client and provider, correlating request and response and CSRF/replay protection. (recommended).
- nonce : echos back the nonce value in the identity token (for replay protection), Required when identity tokens is transmitted via the browser channel.
Request Example
GET https://sso.eu.edenred.io/connect/authorize HTTP 1.1
?client_id=12e7e1dd73e64735a1ee51f73bf9a3a5
&response_type=code
&scope=openid%20%20autoconnect
&redirect_uri=https%3A%2F%2Fwww.myedenred.be%2FAccount%2FSignInCallback
&state=c51f9804a00d434fb01aef820c94ca62
&nonce=43aa3cb027424579820ed46fd24fdafe
&acr_values=tenant%3Abe-ben
&ui_locales=FR
B/ Consent Screen
After successful authentication, a consent page pops up.
A consent page normally renders the display name of the current user, the display name of the client requesting access, the logo of the client, a link for more information about the client, and the list of resources the client is requesting access to. It’s also common to allow the user to indicate that their consent should be “remembered” so they are not prompted again in the future for the same client.
Once the user has provided consent, the consent page must inform your IdentityServer of the consent, and then the browser must be redirected back to the authorization endpoint.
C/ Redirected response
HTTP/1.1 302 Found
Location: https://redirect_uri/callback?code={{code}}&scope={{scopes}}&state={{state}}&session_state={{sessionState}}
Example of Redirect
https://redirect_uri/callback
?code=35C3E7F0C5132BC2D588C29BA5C0EF9FD764EEB500488E39D8F864AFF0319C12
&scope=openid%20profile%20offline_access%20email
&state=statesOne
&session_state=arfoASULTUTzj3v6v2jNygeRnMKQ4ml1OYtLhnyatak.608522AE6F2BD29FB235E285B5049135
This callback must be handled server-side in order to get the code in query params and use it later to retive access-token and refresh token from Connect.
5/ Retrieve Token using Code
A/ Retrieve Token Request
After Retrieving the code, the client then opens a back-channel communication to the token service to retrieve the tokens from Connect Token Endpoint.
POST /connect/token HTTP 1.1
CONTENT-TYPE application/x-www-form-urlencoded
BODY :
client_id={{authentication_clientId}}&
client_secret={{authentication_secret}}&
grant_type={{authorization_code}}&
code={{authentication_code}}&
redirect_uri={{redirect_url}}
- client_id *: unique idenitifier the client.
- client_secret *: client secret.
- grant_type : for Authorization Code Flow the value of {{authorization_code}} should be *authorization_code.
- redirect_uri *: the same redirect uri used to retrive Code from authorization endpoint.
- code *: The code recived in the callback url.
Example of Request
POST https://sso.eu.edenred.io/connect/token HTTP 1.1
CONTENT-TYPE application/x-www-form-urlencoded
BODY :
client_id=934fc8072faa423086cac8c6c62a2b5e
&client_secret=secret
&grant_type=authorization_code
&code=B1CEDCFE0F57F5966AAC7361033EA8761A965415010258909FA2EF50CD5F7B60
&redirect_uri=https://redirect_uri/callback
B/ Retrieve Token Response
Connect will return a json response containing all the required information to authenticate: The id_token , access_token , expires_in , token_type , refresh_token , scope.
HTTP/1.1 200 OK
Content-Type: application/json
{
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjcyOTAyQkZDQkI4Njk1NTc5NUU1NThDNzNEQUZEMTNFIiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo1MDAxIiwibmJmIjoxNjQ4NzQwMzM4LCJpYXQiOjE2NDg3NDAzMzgsImV4cCI6MTY0ODc0MDYzOCwiYXVkIjoiOTM0ZmM4MDcyZmQ4NDIzMDg2Y2FjOGM2YzYyYTJiNWUiLCJhbXIiOlsicHdkIl0sImF0X2hhc2giOiJSS21XdWVPeWxFV3ViWEYtMl9HLUl3Iiwic19oYXNoIjoiM1hRdlJOVVVMbXJFVGNodmxaTER6USIsInNpZCI6IjkzNTRDQzM1RDY5QjJGRTQxOTkwREY2NzlCQ0VGRjBBIiwic3ViIjoibW9ja1xcbW9jayIsImF1dGhfdGldsdsdsdZSI6MTY0ODczNjYyMywiaWRwIjoibG9jYWwiLCJ0ZW5hbnQiOiJtb2NrIiwidXNlcm5hbWUiOiJtb2NrIn0.LxpPH3EWtfGU98S4QtrR0NTknCLfFkBJqAc_kfQ4O3eEOLT6X3UclsvS6S02M7QLQMlkPFemOu_tthyDOxznidQA_DkZmsa2zoEfCpupjsI5Hvuk5_xXD-NJMiXWHWE2QlL0vQkuJa-Qrw_2wZkvVhJmEHJ7z4lD-fEEkmGbSMo6DuhQ95b5okEhG4-IPULALyesIycbZiQWJTujOuT6RnkoKNOJ4wFLQHuznx3uLUFCA5IrK0Rvm4U5_cM_DIlXguPOhKi-oT3rYmr8DfVIAyl3YRwqSfV5GwZadYTqOHbT-iwDkXR6zlzYRGEmS5HOTjdhG4AiwQOIZkM0OUftmA",
"access_token": "C0D2DF58D0140728952F53B4BB8CA94D28D3B0CCD88695115BEC0384C7246FF36",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "94BDBF77BB1FAF97F79BEE68ACE0AA966CEAB1305FEAB0D5F1D82CBEAA723112",
"scope": "openid profile offline_access email"
}
Tokens must be stored securely server-side. Connect token is a JWT (standalone) token containing information about user and authentication process (https://jwt.io), it has a very short lifetime.
6/ User Info Endpoint
A/ User Info Request
The UserInfo endpoint can be used to retrieve claims about a user. The caller needs to send a valid access token. Depending on the granted scopes, the UserInfo endpoint will return the mapped claims.
GET /connect/userinfo HTTP/1.1
Authorization: Bearer {{access_token}}
B/ UserInfo Response
The user infos informations , depends to the client allowed scopes, and the scopes requested while authorization.
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "Teant\\username",
"name": "Bob Smith",
"tenant": "Teant",
}
7/ Refreshing Token
To get a new access token, you send the refresh token to the token endpoint. This will result in a new token response containing a new access token and its expiration and potentially also a new refresh token depending on the client configuration.
A/ Refreshing Token Request
POST /connect/token HTTP/1.1
CONTENT-TYPE application/x-www-form-urlencoded
BODY :
client_id={{authentication-clientId}}&
client_secret={{authentication-clientSecret}}&
grant_type=refresh_token&
refresh_token={{refresh_token}}
B/ Refreshing Token Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id_token": "{{Jwt_token}}",
"access_token": "C0D2DF58D0140728952F53B4BB8CA94D28D3B0CCD88695115BEC0384C7246FF36",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "94BDBF77BB1FAF97F79BEE68ACE0AA966CEAB1305FEAB0D5F1D82CBEAA723112",
"scope": "openid profile offline_access email"
}
Logout
To use the end session endpoint a client application will redirect the user’s browser to the end session URL. All applications that the user has logged into via the browser during the user’s session can participate in the sign-out.
- id_token_hint: When the user is redirected to the endpoint, they will be prompted if they really want to sign-out. This prompt can be bypassed by a client sending the original id_token received from authentication. This is passed as a query string parameter called id_token_hint.
- post_logout_redirect_uri: If a valid id_token_hint is passed, then the client may also send a post_logout_redirect_uri parameter. This can be used to allow the user to redirect back to the client after sign-out. The value must match one of the client’s pre-configured PostLogoutRedirectUris.
- state: If a valid post_logout_redirect_uri is passed, then the client may also send a state parameter. This will be returned back to the client as a query string parameter after the user redirects back to the client. This is typically used by clients to round-trip state across the redirect.
GET /connect/endsession?id_token_hint={{tokenId}}&post_logout_redirect_uri={{postLogoutRedirectUri}}&state={{state}
Host: {{authentication-url}}
Revocation Endpoint
This endpoint allows revoking access tokens (reference tokens only) and refresh token. It implements the token revocation specification (RFC 7009).
- token : the token to revoke (required)
- *token_type_hint : either access_token or refresh_token (optional)
POST /connect/revocation HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
token={{token}}&
token_type_hint={{token_type_hint}}
Full Revocation Endpoint
This endpoint allows full revoking access to a specific user, all current tokens in all allowed tenants for a client. The client should have the scope "revocation" in the allowed scopes.
POST /connect/fullrevocation
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {{token}}
username={{username}}
Introspect Endpoint
It can be used to validate reference tokens (or JWTs if the consumer does not have support for appropriate JWT or cryptographic libraries). The introspection endpoint requires authentication - since the client of an introspection endpoint is an API, you configure the secret on the ApiResource.
POST /connect/introspect
Content-Type: application/x-www-form-urlencoded
Authorization: Basic xxxyyy
token={{token}}
Consuming Payment APIs
Edenred Payment Services are composed of a set of five (5) APIs:
Retrieve daily available balance
Place an authorization (amount reservation)
Cancel an authorization
Capture an authorization (confirm it and trigger clearing)
* Refund a captured transaction
All these APIs are protected using OAuth 2.0 and a pair of "payment-clientId" & "payment-ClientSecret. They require a valid access_token in Authorization header and both Client-Id & Client-Secret headers.
e.g. :
http
GET /v2/users/{{username}}/balances?mid={{mid}} HTTP/1.1
Host: {{payment-url}}
Authorization: Bearer {{access_token}}
Content-Type: application/json
Client-Id: {{payment-clientId}}
Client-Secret: {{payment-clientSecret}}
Please refer to the use case per country and the specification for further details on the API implementation