Create a session
The two calls your server makes, authenticate, then create the payment session, then receive the token to hand to your page.
The two steps that happen on your server before your checkout page renders.
1. Authenticate
Section titled “1. Authenticate”Exchange your credentials for an access token. This token lasts a while: cache it and reuse it until expiration.
# jq (https://jqlang.github.io/jq) reads the answers; both steps share $ACCESS_TOKEN.
GRANT=$(curl -s -X POST "https://services.sandbox.payplug-elements.msem.tech/oauth/token" \ -H "content-type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=client_credentials" \ --data-urlencode "client_id=$MERCHANT_ID" \ --data-urlencode "client_secret=$MERCHANT_SECRET")
ACCESS_TOKEN=$(echo "$GRANT" | jq -r .access_token)EXPIRES_IN=$(echo "$GRANT" | jq -r .expires_in)const grant = await fetch("https://services.sandbox.payplug-elements.msem.tech/oauth/token", { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "client_credentials", client_id: MERCHANT_ID, client_secret: MERCHANT_SECRET, }),});const { access_token, expires_in } = await grant.json();import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import java.net.URI;import java.net.URLEncoder;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.util.List;import java.util.Map;import static java.nio.charset.StandardCharsets.UTF_8;
var mapper = new ObjectMapper();var client = HttpClient.newHttpClient();
var form = "grant_type=client_credentials" + "&client_id=" + URLEncoder.encode(MERCHANT_ID, UTF_8) + "&client_secret=" + URLEncoder.encode(MERCHANT_SECRET, UTF_8);
var grant = client.send( HttpRequest.newBuilder(URI.create("https://services.sandbox.payplug-elements.msem.tech/oauth/token")) .header("content-type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(form)) .build(), HttpResponse.BodyHandlers.ofString());
JsonNode token = mapper.readTree(grant.body());String accessToken = token.get("access_token").asText();int expiresIn = token.get("expires_in").asInt();using System.Net.Http.Headers;using System.Net.Http.Json;using System.Text.Json;
var http = new HttpClient();
var grant = await http.PostAsync( "https://services.sandbox.payplug-elements.msem.tech/oauth/token", new FormUrlEncodedContent(new Dictionary<string, string> { ["grant_type"] = "client_credentials", ["client_id"] = MerchantId, ["client_secret"] = MerchantSecret, }));
var token = await grant.Content.ReadFromJsonAsync<JsonElement>();var accessToken = token.GetProperty("access_token").GetString();var expiresIn = token.GetProperty("expires_in").GetInt32();$grant = curl_init("https://services.sandbox.payplug-elements.msem.tech/oauth/token");curl_setopt_array($grant, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query([ 'grant_type' => 'client_credentials', 'client_id' => $merchantId, 'client_secret' => $merchantSecret, ]),]);
$token = json_decode(curl_exec($grant), true);$accessToken = $token['access_token'];$expiresIn = $token['expires_in'];import requests # pip install requests
grant = requests.post( "https://services.sandbox.payplug-elements.msem.tech/oauth/token", data={ "grant_type": "client_credentials", "client_id": MERCHANT_ID, "client_secret": MERCHANT_SECRET, },)
token = grant.json()access_token = token["access_token"]expires_in = token["expires_in"]require "json"require "net/http"
grant = Net::HTTP.post_form( URI("https://services.sandbox.payplug-elements.msem.tech/oauth/token"), "grant_type" => "client_credentials", "client_id" => MERCHANT_ID, "client_secret" => MERCHANT_SECRET)
token = JSON.parse(grant.body)access_token = token["access_token"]expires_in = token["expires_in"]import ( "bytes" "encoding/json" "net/http" "net/url")
grant, err := http.PostForm("https://services.sandbox.payplug-elements.msem.tech/oauth/token", url.Values{ "grant_type": {"client_credentials"}, "client_id": {merchantID}, "client_secret": {merchantSecret},})if err != nil { return err}defer grant.Body.Close()
var token struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"`}if err := json.NewDecoder(grant.Body).Decode(&token); err != nil { return err}use reqwest::Client;use serde_json::{json, Value};
// Cargo.toml — reqwest = { version = "0.12", features = ["json"] }// serde_json = "1"// tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
let http = Client::new();
let token: Value = http .post("https://services.sandbox.payplug-elements.msem.tech/oauth/token") .form(&[ ("grant_type", "client_credentials"), ("client_id", merchant_id), ("client_secret", merchant_secret), ]) .send() .await? .json() .await?;
let access_token = token["access_token"].as_str().unwrap();let expires_in = token["expires_in"].as_u64().unwrap();# jq (https://jqlang.github.io/jq) reads the answers; both steps share $ACCESS_TOKEN.
GRANT=$(curl -s -X POST "https://services.payplug-elements.msem.tech/oauth/token" \ -H "content-type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=client_credentials" \ --data-urlencode "client_id=$MERCHANT_ID" \ --data-urlencode "client_secret=$MERCHANT_SECRET")
ACCESS_TOKEN=$(echo "$GRANT" | jq -r .access_token)EXPIRES_IN=$(echo "$GRANT" | jq -r .expires_in)const grant = await fetch("https://services.payplug-elements.msem.tech/oauth/token", { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "client_credentials", client_id: MERCHANT_ID, client_secret: MERCHANT_SECRET, }),});const { access_token, expires_in } = await grant.json();import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import java.net.URI;import java.net.URLEncoder;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.util.List;import java.util.Map;import static java.nio.charset.StandardCharsets.UTF_8;
var mapper = new ObjectMapper();var client = HttpClient.newHttpClient();
var form = "grant_type=client_credentials" + "&client_id=" + URLEncoder.encode(MERCHANT_ID, UTF_8) + "&client_secret=" + URLEncoder.encode(MERCHANT_SECRET, UTF_8);
var grant = client.send( HttpRequest.newBuilder(URI.create("https://services.payplug-elements.msem.tech/oauth/token")) .header("content-type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(form)) .build(), HttpResponse.BodyHandlers.ofString());
JsonNode token = mapper.readTree(grant.body());String accessToken = token.get("access_token").asText();int expiresIn = token.get("expires_in").asInt();using System.Net.Http.Headers;using System.Net.Http.Json;using System.Text.Json;
var http = new HttpClient();
var grant = await http.PostAsync( "https://services.payplug-elements.msem.tech/oauth/token", new FormUrlEncodedContent(new Dictionary<string, string> { ["grant_type"] = "client_credentials", ["client_id"] = MerchantId, ["client_secret"] = MerchantSecret, }));
var token = await grant.Content.ReadFromJsonAsync<JsonElement>();var accessToken = token.GetProperty("access_token").GetString();var expiresIn = token.GetProperty("expires_in").GetInt32();$grant = curl_init("https://services.payplug-elements.msem.tech/oauth/token");curl_setopt_array($grant, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query([ 'grant_type' => 'client_credentials', 'client_id' => $merchantId, 'client_secret' => $merchantSecret, ]),]);
$token = json_decode(curl_exec($grant), true);$accessToken = $token['access_token'];$expiresIn = $token['expires_in'];import requests # pip install requests
grant = requests.post( "https://services.payplug-elements.msem.tech/oauth/token", data={ "grant_type": "client_credentials", "client_id": MERCHANT_ID, "client_secret": MERCHANT_SECRET, },)
token = grant.json()access_token = token["access_token"]expires_in = token["expires_in"]require "json"require "net/http"
grant = Net::HTTP.post_form( URI("https://services.payplug-elements.msem.tech/oauth/token"), "grant_type" => "client_credentials", "client_id" => MERCHANT_ID, "client_secret" => MERCHANT_SECRET)
token = JSON.parse(grant.body)access_token = token["access_token"]expires_in = token["expires_in"]import ( "bytes" "encoding/json" "net/http" "net/url")
grant, err := http.PostForm("https://services.payplug-elements.msem.tech/oauth/token", url.Values{ "grant_type": {"client_credentials"}, "client_id": {merchantID}, "client_secret": {merchantSecret},})if err != nil { return err}defer grant.Body.Close()
var token struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"`}if err := json.NewDecoder(grant.Body).Decode(&token); err != nil { return err}use reqwest::Client;use serde_json::{json, Value};
// Cargo.toml — reqwest = { version = "0.12", features = ["json"] }// serde_json = "1"// tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
let http = Client::new();
let token: Value = http .post("https://services.payplug-elements.msem.tech/oauth/token") .form(&[ ("grant_type", "client_credentials"), ("client_id", merchant_id), ("client_secret", merchant_secret), ]) .send() .await? .json() .await?;
let access_token = token["access_token"].as_str().unwrap();let expires_in = token["expires_in"].as_u64().unwrap();2. Create the session
Section titled “2. Create the session”Now declare a payment session for an order.
ELEMENTS_TOKEN=$(curl -s -X POST "https://services.sandbox.payplug-elements.msem.tech/api/sessions" \ -H "content-type: application/json" \ -H "authorization: Bearer $ACCESS_TOKEN" \ -d '{ "currency": "EUR", "total": 100000, "orderId": "EP-123456", "methods": [{ "method": "card" }], "returnUrl": "https://shop.example.com/checkout" }' | jq -r .elementsToken)const response = await fetch("https://services.sandbox.payplug-elements.msem.tech/api/sessions", { method: "POST", headers: { "content-type": "application/json", authorization: `Bearer ${access_token}` }, body: JSON.stringify({ currency: "EUR", total: 1000_00, // in the currency's minor unit — cents here orderId: "EP-123456", // YOUR reference for this order methods: [{ method: "card" }], returnUrl: "https://shop.example.com/checkout", // where redirected methods come back }),});const { elementsToken } = await response.json();var body = mapper.writeValueAsString(Map.of( "currency", "EUR", "total", 1000_00, // in the currency's minor unit — cents here "orderId", "EP-123456", // YOUR reference for this order "methods", List.of(Map.of("method", "card")), "returnUrl", "https://shop.example.com/checkout")); // where redirected methods come back
var response = client.send( HttpRequest.newBuilder(URI.create("https://services.sandbox.payplug-elements.msem.tech/api/sessions")) .header("content-type", "application/json") .header("authorization", "Bearer " + accessToken) .POST(HttpRequest.BodyPublishers.ofString(body)) .build(), HttpResponse.BodyHandlers.ofString());
String elementsToken = mapper.readTree(response.body()).get("elementsToken").asText();http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await http.PostAsJsonAsync("https://services.sandbox.payplug-elements.msem.tech/api/sessions", new{ currency = "EUR", total = 1000_00, // in the currency's minor unit — cents here orderId = "EP-123456", // YOUR reference for this order methods = new[] { new { method = "card" } }, returnUrl = "https://shop.example.com/checkout", // where redirected methods come back});
var session = await response.Content.ReadFromJsonAsync<JsonElement>();var elementsToken = session.GetProperty("elementsToken").GetString();$session = curl_init("https://services.sandbox.payplug-elements.msem.tech/api/sessions");curl_setopt_array($session, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'content-type: application/json', "authorization: Bearer $accessToken", ], CURLOPT_POSTFIELDS => json_encode([ 'currency' => 'EUR', 'total' => 1000_00, // in the currency's minor unit — cents here 'orderId' => 'EP-123456', // YOUR reference for this order 'methods' => [['method' => 'card']], 'returnUrl' => 'https://shop.example.com/checkout', // where redirected methods come back ]),]);
$elementsToken = json_decode(curl_exec($session), true)['elementsToken'];response = requests.post( "https://services.sandbox.payplug-elements.msem.tech/api/sessions", headers={"authorization": f"Bearer {access_token}"}, json={ "currency": "EUR", "total": 1000_00, # in the currency's minor unit — cents here "orderId": "EP-123456", # YOUR reference for this order "methods": [{"method": "card"}], "returnUrl": "https://shop.example.com/checkout", # where redirected methods come back },)
elements_token = response.json()["elementsToken"]body = { currency: "EUR", total: 1000_00, # in the currency's minor unit — cents here orderId: "EP-123456", # YOUR reference for this order methods: [{ method: "card" }], returnUrl: "https://shop.example.com/checkout" # where redirected methods come back}
response = Net::HTTP.post( URI("https://services.sandbox.payplug-elements.msem.tech/api/sessions"), body.to_json, "content-type" => "application/json", "authorization" => "Bearer #{access_token}")
elements_token = JSON.parse(response.body)["elementsToken"]body, err := json.Marshal(map[string]any{ "currency": "EUR", "total": 1000_00, // in the currency's minor unit — cents here "orderId": "EP-123456", // YOUR reference for this order "methods": []any{map[string]any{"method": "card"}}, "returnUrl": "https://shop.example.com/checkout", // where redirected methods come back})if err != nil { return err}
request, err := http.NewRequest("POST", "https://services.sandbox.payplug-elements.msem.tech/api/sessions", bytes.NewReader(body))if err != nil { return err}request.Header.Set("content-type", "application/json")request.Header.Set("authorization", "Bearer "+token.AccessToken)
response, err := http.DefaultClient.Do(request)if err != nil { return err}defer response.Body.Close()
var session struct { ElementsToken string `json:"elementsToken"`}if err := json.NewDecoder(response.Body).Decode(&session); err != nil { return err}let session: Value = http .post("https://services.sandbox.payplug-elements.msem.tech/api/sessions") .bearer_auth(access_token) .json(&json!({ "currency": "EUR", "total": 1000_00, // in the currency's minor unit — cents here "orderId": "EP-123456", // YOUR reference for this order "methods": [{ "method": "card" }], "returnUrl": "https://shop.example.com/checkout", // where redirected methods come back })) .send() .await? .json() .await?;
let elements_token = session["elementsToken"].as_str().unwrap();ELEMENTS_TOKEN=$(curl -s -X POST "https://services.payplug-elements.msem.tech/api/sessions" \ -H "content-type: application/json" \ -H "authorization: Bearer $ACCESS_TOKEN" \ -d '{ "currency": "EUR", "total": 100000, "orderId": "EP-123456", "methods": [{ "method": "card" }], "returnUrl": "https://shop.example.com/checkout" }' | jq -r .elementsToken)const response = await fetch("https://services.payplug-elements.msem.tech/api/sessions", { method: "POST", headers: { "content-type": "application/json", authorization: `Bearer ${access_token}` }, body: JSON.stringify({ currency: "EUR", total: 1000_00, // in the currency's minor unit — cents here orderId: "EP-123456", // YOUR reference for this order methods: [{ method: "card" }], returnUrl: "https://shop.example.com/checkout", // where redirected methods come back }),});const { elementsToken } = await response.json();var body = mapper.writeValueAsString(Map.of( "currency", "EUR", "total", 1000_00, // in the currency's minor unit — cents here "orderId", "EP-123456", // YOUR reference for this order "methods", List.of(Map.of("method", "card")), "returnUrl", "https://shop.example.com/checkout")); // where redirected methods come back
var response = client.send( HttpRequest.newBuilder(URI.create("https://services.payplug-elements.msem.tech/api/sessions")) .header("content-type", "application/json") .header("authorization", "Bearer " + accessToken) .POST(HttpRequest.BodyPublishers.ofString(body)) .build(), HttpResponse.BodyHandlers.ofString());
String elementsToken = mapper.readTree(response.body()).get("elementsToken").asText();http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await http.PostAsJsonAsync("https://services.payplug-elements.msem.tech/api/sessions", new{ currency = "EUR", total = 1000_00, // in the currency's minor unit — cents here orderId = "EP-123456", // YOUR reference for this order methods = new[] { new { method = "card" } }, returnUrl = "https://shop.example.com/checkout", // where redirected methods come back});
var session = await response.Content.ReadFromJsonAsync<JsonElement>();var elementsToken = session.GetProperty("elementsToken").GetString();$session = curl_init("https://services.payplug-elements.msem.tech/api/sessions");curl_setopt_array($session, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'content-type: application/json', "authorization: Bearer $accessToken", ], CURLOPT_POSTFIELDS => json_encode([ 'currency' => 'EUR', 'total' => 1000_00, // in the currency's minor unit — cents here 'orderId' => 'EP-123456', // YOUR reference for this order 'methods' => [['method' => 'card']], 'returnUrl' => 'https://shop.example.com/checkout', // where redirected methods come back ]),]);
$elementsToken = json_decode(curl_exec($session), true)['elementsToken'];response = requests.post( "https://services.payplug-elements.msem.tech/api/sessions", headers={"authorization": f"Bearer {access_token}"}, json={ "currency": "EUR", "total": 1000_00, # in the currency's minor unit — cents here "orderId": "EP-123456", # YOUR reference for this order "methods": [{"method": "card"}], "returnUrl": "https://shop.example.com/checkout", # where redirected methods come back },)
elements_token = response.json()["elementsToken"]body = { currency: "EUR", total: 1000_00, # in the currency's minor unit — cents here orderId: "EP-123456", # YOUR reference for this order methods: [{ method: "card" }], returnUrl: "https://shop.example.com/checkout" # where redirected methods come back}
response = Net::HTTP.post( URI("https://services.payplug-elements.msem.tech/api/sessions"), body.to_json, "content-type" => "application/json", "authorization" => "Bearer #{access_token}")
elements_token = JSON.parse(response.body)["elementsToken"]body, err := json.Marshal(map[string]any{ "currency": "EUR", "total": 1000_00, // in the currency's minor unit — cents here "orderId": "EP-123456", // YOUR reference for this order "methods": []any{map[string]any{"method": "card"}}, "returnUrl": "https://shop.example.com/checkout", // where redirected methods come back})if err != nil { return err}
request, err := http.NewRequest("POST", "https://services.payplug-elements.msem.tech/api/sessions", bytes.NewReader(body))if err != nil { return err}request.Header.Set("content-type", "application/json")request.Header.Set("authorization", "Bearer "+token.AccessToken)
response, err := http.DefaultClient.Do(request)if err != nil { return err}defer response.Body.Close()
var session struct { ElementsToken string `json:"elementsToken"`}if err := json.NewDecoder(response.Body).Decode(&session); err != nil { return err}let session: Value = http .post("https://services.payplug-elements.msem.tech/api/sessions") .bearer_auth(access_token) .json(&json!({ "currency": "EUR", "total": 1000_00, // in the currency's minor unit — cents here "orderId": "EP-123456", // YOUR reference for this order "methods": [{ "method": "card" }], "returnUrl": "https://shop.example.com/checkout", // where redirected methods come back })) .send() .await? .json() .await?;
let elements_token = session["elementsToken"].as_str().unwrap();A few things worth knowing about the request body:
- The merchant is inferred from the token: a session belongs to the merchant who authenticated.
orderIdis required and travels with every PSP transaction: a split payment sends several operations with that same reference.totaland every amount in this API are in minor units (cents for euros).methodsdeclares what you want for this order. For the configuration of the payment methods, see payment methods.
3. Hand the token to your page
Section titled “3. Hand the token to your page”The answer carries an opaque, short-lived elementsToken. That is the only thing the browser ever needs.
Your page takes it from there: see show the elements.