{
	"info": {
		"_postman_id": "c87668ec-7773-4359-9312-f78f441bdc7f",
		"name": "E-Commerce Payment Gateway",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "Unified Merchant API",
			"item": [
				{
					"name": "Payments",
					"item": [
						{
							"name": "Sessions",
							"item": [
								{
									"name": "Card",
									"item": [
										{
											"name": "Get encryption key",
											"event": [
												{
													"listen": "test",
													"script": {
														"exec": [
															"pm.environment.set(\"card_encryption_jwk\", pm.response.text());"
														],
														"type": "text/javascript",
														"packages": {},
														"requests": {}
													}
												}
											],
											"request": {
												"auth": {
													"type": "noauth"
												},
												"method": "GET",
												"header": [],
												"url": {
													"raw": "{{protocol}}://{{checkout-host}}/api/keys/card-encryption.jwk",
													"protocol": "{{protocol}}",
													"host": [
														"{{checkout-host}}"
													],
													"path": [
														"api",
														"keys",
														"card-encryption.jwk"
													]
												}
											},
											"response": []
										},
										{
											"name": "Create card session",
											"event": [
												{
													"listen": "prerequest",
													"script": {
														"exec": [
															"const jose = pm.require('npm:jose@6.0.11')\r",
															"\r",
															"// get key\r",
															"if (!pm.environment.get(\"card_encryption_jwk\")) {\r",
															"  throw new Error(\"Please run 'Get encryption key' before sending card data\")\r",
															"}\r",
															"const keyJson = JSON.parse(pm.environment.get(\"card_encryption_jwk\"))\r",
															"\r",
															"// import JWK into jose lib\r",
															"const key = await jose.importJWK(keyJson)\r",
															"\r",
															"// get request body\r",
															"const body = JSON.parse(pm.request.body.toString().replace(/\\/\\/.*$/gm, ''))\r",
															"\r",
															"// encrypt and compose JWE data\r",
															"const jwe = await new jose.CompactEncrypt(new TextEncoder().encode(JSON.stringify(body.clearCard)))\r",
															"    .setProtectedHeader({ kid: keyJson.kid, cty: 'application/json', enc: 'A256GCM', alg: keyJson.alg })\r",
															"    .encrypt(key)\r",
															"\r",
															"// update body\r",
															"body.encryptedCard = { jweCompact: jwe }\r",
															"delete body.clearCard\r",
															"\r",
															"pm.request.body.update({\r",
															"  mode: 'raw',\r",
															"  raw: JSON.stringify(body),\r",
															"  options: {\r",
															"    raw: {\r",
															"      language: 'json'\r",
															"    }\r",
															"  }\r",
															"})\r",
															""
														],
														"type": "text/javascript",
														"packages": {
															"npm:jose@6.0.11": {
																"id": "npm:jose@6.0.11"
															}
														},
														"requests": {}
													}
												},
												{
													"listen": "test",
													"script": {
														"exec": [
															"pm.environment.set(\"sessionId\", pm.response.json().sessionId);\r",
															""
														],
														"type": "text/javascript",
														"packages": {},
														"requests": {}
													}
												}
											],
											"request": {
												"method": "POST",
												"header": [],
												"body": {
													"mode": "raw",
													"raw": "{\r\n  \"clearCard\": {\r\n    \"cardholderName\": \"Test User\",\r\n    \"cardNumber\": \"5186000000000005\", // Visa - 4000000000000002, MC - 5186000000000005, 5186000000000013\r\n    \"expiry\": {\r\n      \"month\": \"12\",\r\n      \"year\": \"30\"\r\n    },\r\n    \"csc\": \"123\"\r\n  }\r\n}",
													"options": {
														"raw": {
															"language": "json"
														}
													}
												},
												"url": {
													"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/sessions/card",
													"protocol": "{{protocol}}",
													"host": [
														"{{api-host}}"
													],
													"path": [
														"egw",
														"v1",
														"payments",
														"{{paymentId}}",
														"sessions",
														"card"
													]
												}
											},
											"response": []
										},
										{
											"name": "Get card session",
											"request": {
												"method": "GET",
												"header": [],
												"url": {
													"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/sessions/{{sessionId}}/card",
													"protocol": "{{protocol}}",
													"host": [
														"{{api-host}}"
													],
													"path": [
														"egw",
														"v1",
														"payments",
														"{{paymentId}}",
														"sessions",
														"{{sessionId}}",
														"card"
													]
												}
											},
											"response": []
										},
										{
											"name": "Initiate 3DS authentication",
											"request": {
												"method": "PATCH",
												"header": [],
												"body": {
													"mode": "raw",
													"raw": "{\r\n  \"browserAcceptHeader\": \"*/*\",\r\n  \"browserIp\": \"127.0.0.1\",\r\n  \"browserJavaEnabled\": true,\r\n  \"browserJavascriptEnabled\": true,\r\n  \"browserLanguage\": \"en-US\",\r\n  \"browserColorDepth\": \"48\",\r\n  \"browserScreenHeight\": \"1440\",\r\n  \"browserScreenWidth\": \"2560\",\r\n  \"browserTZ\": \"0\",\r\n  \"browserUserAgent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36\"\r\n}",
													"options": {
														"raw": {
															"language": "json"
														}
													}
												},
												"url": {
													"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/sessions/{{sessionId}}/card/three-ds/authentication",
													"protocol": "{{protocol}}",
													"host": [
														"{{api-host}}"
													],
													"path": [
														"egw",
														"v1",
														"payments",
														"{{paymentId}}",
														"sessions",
														"{{sessionId}}",
														"card",
														"three-ds",
														"authentication"
													]
												}
											},
											"response": []
										},
										{
											"name": "Complete 3DS challenge",
											"request": {
												"method": "PATCH",
												"header": [],
												"body": {
													"mode": "raw",
													"raw": "{\r\n  \"cres\": \"<base64 encoded CRes, as received from the ACS>\"\r\n}",
													"options": {
														"raw": {
															"language": "json"
														}
													}
												},
												"url": {
													"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/sessions/{{sessionId}}/card/three-ds/challenge-result",
													"protocol": "{{protocol}}",
													"host": [
														"{{api-host}}"
													],
													"path": [
														"egw",
														"v1",
														"payments",
														"{{paymentId}}",
														"sessions",
														"{{sessionId}}",
														"card",
														"three-ds",
														"challenge-result"
													]
												}
											},
											"response": []
										}
									]
								},
								{
									"name": "Token",
									"item": [
										{
											"name": "Create token session",
											"event": [
												{
													"listen": "test",
													"script": {
														"exec": [
															"pm.environment.set(\"sessionId\", pm.response.json().sessionId);\r",
															""
														],
														"type": "text/javascript",
														"packages": {}
													}
												}
											],
											"request": {
												"method": "POST",
												"header": [],
												"body": {
													"mode": "raw",
													"raw": "{\r\n  \"gatewayTokenId\": \"{{gatewayTokenId}}\"\r\n}",
													"options": {
														"raw": {
															"language": "json"
														}
													}
												},
												"url": {
													"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/sessions/token",
													"protocol": "{{protocol}}",
													"host": [
														"{{api-host}}"
													],
													"path": [
														"egw",
														"v1",
														"payments",
														"{{paymentId}}",
														"sessions",
														"token"
													]
												}
											},
											"response": []
										}
									]
								}
							]
						},
						{
							"name": "Initiate CIT",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.environment.set(\"paymentId\", pm.response.json().paymentId);\r",
											""
										],
										"type": "text/javascript",
										"packages": {},
										"requests": {}
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript",
										"packages": {},
										"requests": {}
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"participantId\": \"{{egwApiParticipantId}}\",\r\n  \"shopAgreementId\": \"{{egwApiShopAgreementId}}\",\r\n  \"channel\": \"BROWSER\",\r\n  \"orderNumber\": \"{{$guid}}\",\r\n  \"instructedAmount\": {\r\n    \"currency\": \"EUR\",\r\n    \"amount\": \"43.00\"\r\n  },\r\n  \"customer\": {\r\n    \"name\": \"{{$randomFullName}}\",\r\n    \"email\": \"{{$randomExampleEmail}}\",\r\n    \"phone\": \"+37120000000\"\r\n  },\r\n  \"shippingAddress\": {\r\n    \"city\": \"Riga\",\r\n    \"country\": \"LV\",\r\n    \"postalCode\": \"LV-1045\",\r\n    \"addressLine1\": \"Roberta Hirša iela 1\"\r\n  },\r\n  \"billingAddress\": {\r\n    \"city\": \"Riga\",\r\n    \"country\": \"LV\",\r\n    \"postalCode\": \"LV-1045\",\r\n    \"addressLine1\": \"Roberta Hirša iela 1\"\r\n  },\r\n  \"shopRedirectUrl\": \"{{protocol}}://{{merchant-portal-host}}/demostore\",\r\n  \"preferredLocale\": \"en\",\r\n  \"preferredCountry\": \"LV\",\r\n  // \"setupToken\": {\r\n  //   \"required\": false,\r\n  //   \"purposes\": [\"CIT\", \"UNSCHEDULED\"]\r\n  // },\r\n  \"description\": \"Test payment\",\r\n  \"basket\": {\r\n    \"subtotalAmount\": {\r\n      \"currency\": \"EUR\",\r\n      \"amount\": \"38.50\"\r\n    },\r\n    \"salesTaxAmount\": {\r\n      \"currency\": \"EUR\",\r\n      \"amount\": \"2.50\"\r\n    },\r\n    \"shippingAmount\": {\r\n      \"currency\": \"EUR\",\r\n      \"amount\": \"2.00\"\r\n    },\r\n    \"items\": [\r\n      {\r\n        \"name\": \"{{$randomProduct}}\",\r\n        \"quantity\": 1,\r\n        \"price\": {\r\n          \"currency\": \"EUR\",\r\n          \"amount\": \"10\"\r\n        }\r\n      },\r\n      {\r\n        \"name\": \"{{$randomProduct}}\",\r\n        \"quantity\": 2,\r\n        \"price\": {\r\n          \"currency\": \"EUR\",\r\n          \"amount\": \"15.50\"\r\n        }\r\n      }\r\n    ]\r\n  }\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/cit",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"payments",
										"cit"
									]
								}
							},
							"response": []
						},
						{
							"name": "Initiate MIT",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.environment.set(\"paymentId\", pm.response.json().paymentId);\r",
											""
										],
										"type": "text/javascript",
										"packages": {},
										"requests": {}
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript",
										"packages": {},
										"requests": {}
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"participantId\": \"{{egwApiParticipantId}}\",\r\n  \"shopAgreementId\": \"{{egwApiShopAgreementId}}\",\r\n  \"channel\": \"RECURRING\",\r\n  \"orderNumber\": \"{{$guid}}\",\r\n  \"instructedAmount\": {\r\n    \"currency\": \"EUR\",\r\n    \"amount\": \"43.00\"\r\n  },\r\n  \"customer\": {\r\n    \"name\": \"{{$randomFullName}}\",\r\n    \"email\": \"{{$randomExampleEmail}}\",\r\n    \"phone\": \"+37120000000\"\r\n  },\r\n  \"shippingAddress\": {\r\n    \"city\": \"Riga\",\r\n    \"country\": \"LV\",\r\n    \"postalCode\": \"LV-1045\",\r\n    \"addressLine1\": \"Roberta Hirša iela 1\"\r\n  },\r\n  \"billingAddress\": {\r\n    \"city\": \"Riga\",\r\n    \"country\": \"LV\",\r\n    \"postalCode\": \"LV-1045\",\r\n    \"addressLine1\": \"Roberta Hirša iela 1\"\r\n  },\r\n  \"description\": \"Test payment\",\r\n  \"basket\": {\r\n    \"subtotalAmount\": {\r\n      \"currency\": \"EUR\",\r\n      \"amount\": \"38.50\"\r\n    },\r\n    \"salesTaxAmount\": {\r\n      \"currency\": \"EUR\",\r\n      \"amount\": \"2.50\"\r\n    },\r\n    \"shippingAmount\": {\r\n      \"currency\": \"EUR\",\r\n      \"amount\": \"2.00\"\r\n    },\r\n    \"items\": [\r\n      {\r\n        \"name\": \"{{$randomProduct}}\",\r\n        \"quantity\": 1,\r\n        \"price\": {\r\n          \"currency\": \"EUR\",\r\n          \"amount\": \"10\"\r\n        }\r\n      },\r\n      {\r\n        \"name\": \"{{$randomProduct}}\",\r\n        \"quantity\": 2,\r\n        \"price\": {\r\n          \"currency\": \"EUR\",\r\n          \"amount\": \"15.50\"\r\n        }\r\n      }\r\n    ]\r\n  }\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/mit",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"payments",
										"mit"
									]
								}
							},
							"response": []
						},
						{
							"name": "Get payment",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.environment.set(\"gatewayTokenId\", pm.response.json().paymentMethod?.gatewayTokenId);\r",
											""
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"request": {
								"method": "GET",
								"header": [],
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"payments",
										"{{paymentId}}"
									]
								}
							},
							"response": []
						},
						{
							"name": "Capture payment",
							"request": {
								"method": "PATCH",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"instructedAmount\": {\r\n    \"currency\": \"EUR\",\r\n    \"amount\": \"10.20\"\r\n  }\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/capture",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"payments",
										"{{paymentId}}",
										"capture"
									]
								}
							},
							"response": []
						},
						{
							"name": "Cancel payment",
							"request": {
								"method": "PATCH",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"reason\": \"CUSTOMER_CANCELLED\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/payments/{{paymentId}}/cancel",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"payments",
										"{{paymentId}}",
										"cancel"
									]
								}
							},
							"response": []
						}
					],
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"type": "text/javascript",
								"packages": {},
								"exec": [
									""
								]
							}
						},
						{
							"listen": "test",
							"script": {
								"type": "text/javascript",
								"packages": {},
								"exec": [
									""
								]
							}
						}
					]
				},
				{
					"name": "Shops",
					"item": [
						{
							"name": "Get shop details",
							"request": {
								"method": "GET",
								"header": [],
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/shops/{{egwApiShopAgreementId}}",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"shops",
										"{{egwApiShopAgreementId}}"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Tokens",
					"item": [
						{
							"name": "Get token",
							"request": {
								"method": "GET",
								"header": [],
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/tokens/{{gatewayTokenId}}",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"tokens",
										"{{gatewayTokenId}}"
									]
								}
							},
							"response": []
						},
						{
							"name": "Deactivate token",
							"request": {
								"method": "DELETE",
								"header": [],
								"url": {
									"raw": "{{protocol}}://{{api-host}}/egw/v1/tokens/{{gatewayTokenId}}",
									"protocol": "{{protocol}}",
									"host": [
										"{{api-host}}"
									],
									"path": [
										"egw",
										"v1",
										"tokens",
										"{{gatewayTokenId}}"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Get access token",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"\r",
									"const accessToken = pm.response.json().access_token;\r",
									"const tokenPayloadBase64 = accessToken.split('.')[1];\r",
									"const tokenPayload = JSON.parse(atob(tokenPayloadBase64));\r",
									"\r",
									"pm.environment.set(\"egwApiToken\", accessToken)\r",
									"pm.environment.set(\"egwApiParticipantId\", tokenPayload.participantId)\r",
									"pm.environment.set(\"egwApiShopAgreementId\", tokenPayload.agreementId)\r",
									""
								],
								"type": "text/javascript",
								"packages": {},
								"requests": {}
							}
						}
					],
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [],
						"body": {
							"mode": "urlencoded",
							"urlencoded": [
								{
									"key": "grant_type",
									"value": "client_credentials",
									"type": "text"
								},
								{
									"key": "client_id",
									"value": "{{shop-client-id}}",
									"type": "text"
								},
								{
									"key": "client_secret",
									"value": "{{shop-client-secret}}",
									"type": "text"
								}
							]
						},
						"url": {
							"raw": "{{protocol}}://{{merchant-portal-host}}/auth/realms/{{participants-realm}}/protocol/openid-connect/token",
							"protocol": "{{protocol}}",
							"host": [
								"{{merchant-portal-host}}"
							],
							"path": [
								"auth",
								"realms",
								"{{participants-realm}}",
								"protocol",
								"openid-connect",
								"token"
							]
						}
					},
					"response": []
				}
			],
			"auth": {
				"type": "bearer",
				"bearer": [
					{
						"key": "token",
						"value": "{{egwApiToken}}",
						"type": "string"
					}
				]
			},
			"event": [
				{
					"listen": "prerequest",
					"script": {
						"type": "text/javascript",
						"packages": {},
						"requests": {},
						"exec": [
							"pm.request.addHeader({ key: \"X-Request-Id\", value: \"{{$guid}}\" })\r",
							""
						]
					}
				},
				{
					"listen": "test",
					"script": {
						"type": "text/javascript",
						"packages": {},
						"requests": {},
						"exec": [
							""
						]
					}
				}
			]
		}
	]
}