{
	"info": {
		"_postman_id": "ee3d67e1-7940-439e-8632-963d716603ba",
		"name": "Appota docs",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
		"_exporter_id": "1436004"
	},
	"item": [
		{
			"name": "Thanh toán ATM,CC,EWALLET,MM",
			"item": [
				{
					"name": "v1.0",
					"item": [
						{
							"name": "Tạo order thanh toán",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var order = generateRandomString(9);\r",
											"pm.collectionVariables.set('payment_order_id', order);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.orderId = order\r",
											"let signData = '';\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('payment_request_signature', paymentSignature)"
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(jsonData);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});"
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"orderInfo\": \"test thanh toan\",\r\n    \"amount\": 10000,\r\n    \"bankCode\": \"\",\r\n    \"paymentMethod\": \"ALL\",\r\n    \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n    \"redirectUrl\": \"http://yourwebsite.com/redirect\",\r\n    \"extraData\": \"\",\r\n    \"clientIp\": \"103.53.171.140\",\r\n    \"signature\": \"{{payment_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1/orders/payment/bank",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1",
										"orders",
										"payment",
										"bank"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"orderInfo\": \"test thanh toan\",\r\n    \"amount\": 10000,\r\n    \"bankCode\": \"\",\r\n    \"paymentMethod\": \"ALL\",\r\n    \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n    \"redirectUrl\": \"http://yourwebsite.com/redirect\",\r\n    \"extraData\": \"\",\r\n    \"clientIp\": \"103.53.171.140\",\r\n    \"signature\": \"{{payment_request_signature}}\"\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1/orders/payment/bank",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1",
												"orders",
												"payment",
												"bank"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 08:06:49 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "498"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"orderId\": \"oNwTX5qBl\",\n    \"amount\": 10000,\n    \"paymentUrl\": \"https://payment.dev.appotapay.com/bank/payment/process?tran=dGlkPUFQMjIxNDM0NDczNzM3Jm9yZGVySWQ9b053VFg1cUJsJnRzPTE2NTM4OTgwMDk&sign=44db2b20d2149e072e4aed86c52b21e33917ae951559b1afc7a6c41a07f5a126\",\n    \"signature\": \"21eb9e6656268536d64bfe15f92561334b24d64af6229a73f92c59d775c1a657\"\n}"
								}
							]
						},
						{
							"name": "Kiểm tra trạng thái giao dịch",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"var orderId = pm.collectionVariables.get('payment_order_id');\r",
											"let signData = `orderId=${orderId}`;\r",
											"console.log(signData);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('payment_detail_request_signature', paymentSignature)"
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(jsonData);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});\r",
											"pm.collectionVariables.set('appotapay_trans_id', jsonData.appotapayTransId)"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"signature\": \"{{payment_detail_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1/orders/transaction/bank/status",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1",
										"orders",
										"transaction",
										"bank",
										"status"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"signature\": \"{{payment_detail_request_signature}}\"\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1/orders/transaction/bank/status",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1",
												"orders",
												"transaction",
												"bank",
												"status"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 09:29:04 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"orderId\": \"ISH8mh9B8\",\n    \"amount\": 10000,\n    \"appotapayTransId\": \"AP221434473986\",\n    \"paymentType\": \"WEB\",\n    \"paymentMethod\": \"ATM\",\n    \"bankCode\": \"ABBANK\",\n    \"partnerCode\": \"TEST\",\n    \"apiKey\": \"oMhJpkz7K6HDcR6S\",\n    \"extraData\": \"\",\n    \"currency\": \"VND\",\n    \"transactionTs\": 1653898134,\n    \"signature\": \"6561164addc255d3137f89f3cc5fff08e76fd7a68c62f05776f98c8d7e13628c\"\n}"
								}
							]
						},
						{
							"name": "Hoàn tiền giao dịch",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var refundId = generateRandomString(9);\r",
											"pm.collectionVariables.set('refund_id', refundId);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.refundId = refundId\r",
											"requestBody.appotapayTransId = pm.collectionVariables.get('appotapay_trans_id') || '';\r",
											"let signData = '';\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('refund_signature', paymentSignature)"
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"refundId\": \"{{refund_id}}\",\r\n    \"appotapayTransId\": \"{{appotapay_trans_id}}\",\r\n    \"amount\" : 10000,\r\n    \"reason\": \"Test refund\",\r\n    \"signature\": \"{{refund_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1/transaction/refund",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1",
										"transaction",
										"refund"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"refundId\": \"{{refund_id}}\",\r\n    \"appotapayTransId\": \"{{appotapay_trans_id}}\",\r\n    \"amount\" : 10000,\r\n    \"reason\": \"Test refund\",\r\n    \"signature\": \"{{refund_signature}}\"\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1/transaction/refund",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1",
												"transaction",
												"refund"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 08:11:42 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "498"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"data\": {\n        \"appotapayTransId\": \"AP221434473986\",\n        \"refundId\": \"0cdfc82e-61a9-4db2-954e-a7a814706a8a\",\n        \"refundOriginalId\": \"RVe4pV5GH\",\n        \"amount\": 10000,\n        \"reason\": \"Test refund\",\n        \"status\": \"success\",\n        \"transactionTs\": 1653898300\n    },\n    \"signature\": \"f9676908f85880cb226c6a7e5a7551e4b2caf23f681483906a05b8a491c17bfb\"\n}"
								}
							]
						},
						{
							"name": "Danh sách giao dịch hoàn tiền",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1/refunds?appotapayTransId=&orderId=&refundId=&refundOriginalId=&status=&amount=&startTime=&endTime=&refundType=&page=1&limit=1",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1",
										"refunds"
									],
									"query": [
										{
											"key": "appotapayTransId",
											"value": ""
										},
										{
											"key": "orderId",
											"value": ""
										},
										{
											"key": "refundId",
											"value": ""
										},
										{
											"key": "refundOriginalId",
											"value": ""
										},
										{
											"key": "status",
											"value": ""
										},
										{
											"key": "amount",
											"value": ""
										},
										{
											"key": "startTime",
											"value": ""
										},
										{
											"key": "endTime",
											"value": ""
										},
										{
											"key": "refundType",
											"value": ""
										},
										{
											"key": "page",
											"value": "1"
										},
										{
											"key": "limit",
											"value": "1"
										}
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "GET",
										"header": [],
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1/refunds?appotapayTransId=&orderId=&refundId=&refundOriginalId=&status=&amount=&startTime=&endTime=&refundType=&page=1&limit=1",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1",
												"refunds"
											],
											"query": [
												{
													"key": "appotapayTransId",
													"value": ""
												},
												{
													"key": "orderId",
													"value": ""
												},
												{
													"key": "refundId",
													"value": ""
												},
												{
													"key": "refundOriginalId",
													"value": ""
												},
												{
													"key": "status",
													"value": ""
												},
												{
													"key": "amount",
													"value": ""
												},
												{
													"key": "startTime",
													"value": ""
												},
												{
													"key": "endTime",
													"value": ""
												},
												{
													"key": "refundType",
													"value": ""
												},
												{
													"key": "page",
													"value": "1"
												},
												{
													"key": "limit",
													"value": "1"
												}
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 08:19:52 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"data\": [\n        {\n            \"appotapayTransId\": \"AP221434473986\",\n            \"refundId\": \"0cdfc82e-61a9-4db2-954e-a7a814706a8a\",\n            \"refundOriginalId\": \"RVe4pV5GH\",\n            \"amount\": 10000,\n            \"reason\": \"Test refund\",\n            \"status\": \"success\",\n            \"transactionTs\": 1653898300,\n            \"rejectReason\": null\n        }\n    ],\n    \"meta\": {\n        \"page\": \"1\",\n        \"limit\": \"1\",\n        \"total\": 243109,\n        \"totalAmount\": 20955490138,\n        \"pages\": 243109\n    }\n}"
								}
							]
						},
						{
							"name": "Danh sách giao dịch hoàn tiền theo mã đơn hàng",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"amount\": 10000,\r\n    \"orderInfo\": \"Test payment link\",\r\n    \"expiredAt\": 0,\r\n    \"customerName\":\"Mai Quang Minh\",\r\n    \"customerPhone\": \"0366583945\",\r\n    \"partnerOrderId\": \"{{payment_link_order_id}}\",\r\n    \"signature\": \"{{payment_link_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1/transaction/{{payment_order_id}}/refund",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1",
										"transaction",
										"{{payment_order_id}}",
										"refund"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "GET",
										"header": [],
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1/transaction/{{payment_order_id}}/refund",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1",
												"transaction",
												"{{payment_order_id}}",
												"refund"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 08:21:02 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"data\": {\n        \"appotapayTransId\": \"AP221434473986\",\n        \"orderId\": \"ISH8mh9B8\",\n        \"orderInfo\": \"test thanh toan\",\n        \"partnerCode\": \"TEST\",\n        \"applicationId\": 1,\n        \"amount\": 10000,\n        \"bankCode\": \"ABBANK\",\n        \"paymentMethod\": \"ATM\",\n        \"refundType\": \"total\",\n        \"transactionTs\": 1653898134,\n        \"refundTransactions\": [\n            {\n                \"appotapayTransId\": \"AP221434473986\",\n                \"refundId\": \"0cdfc82e-61a9-4db2-954e-a7a814706a8a\",\n                \"refundOriginalId\": \"RVe4pV5GH\",\n                \"amount\": 10000,\n                \"reason\": \"Test refund\",\n                \"status\": \"success\",\n                \"transactionTs\": 1653898300,\n                \"rejectReason\": null\n            }\n        ]\n    }\n}"
								}
							]
						},
						{
							"name": "Chi tiết giao dịch hoàn tiền",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1/transaction/refund/{{refund_id}}",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1",
										"transaction",
										"refund",
										"{{refund_id}}"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "GET",
										"header": [],
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1/transaction/refund/{{refund_id}}",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1",
												"transaction",
												"refund",
												"{{refund_id}}"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 08:25:39 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "498"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"data\": {\n        \"appotapayTransId\": \"AP221434473986\",\n        \"refundId\": \"0cdfc82e-61a9-4db2-954e-a7a814706a8a\",\n        \"refundOriginalId\": \"RVe4pV5GH\",\n        \"amount\": 10000,\n        \"reason\": \"Test refund\",\n        \"status\": \"success\",\n        \"transactionTs\": 1653898300,\n        \"rejectReason\": \"\"\n    },\n    \"signature\": \"9be259cea0d30a5d482cc3581663f2bc0151221b253905f9fc87a739f30b2207\"\n}"
								}
							]
						}
					]
				},
				{
					"name": "v1.1",
					"item": [
						{
							"name": "Create order",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var order = generateRandomString(9);\r",
											"pm.collectionVariables.set('payment_order_id', order);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.orderId = order\r",
											"let signData = '';\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('payment_request_signature', paymentSignature)"
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"// signData = billCode + errorCode + json_encode(payment)\r",
											"var signArr = {\r",
											"    \"errorCode\": jsonData.errorCode,\r",
											"    \"message\": jsonData.message\r",
											"};\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(signArr);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});"
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"orderInfo\": \"test thanh toan\",\r\n    \"amount\": 10000,\r\n    \"bankCode\": \"\",\r\n    \"paymentMethod\": \"ATM\", \r\n    \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n    \"redirectUrl\": \"http://yourwebsite.com/redirect\",\r\n    \"extraData\": \"\",\r\n    \"clientIp\": \"103.53.171.140\",\r\n    \"signature\": \"{{payment_request_signature}}\",\r\n    \"action\": \"PAY\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1.1/orders/payment/bank",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1.1",
										"orders",
										"payment",
										"bank"
									]
								}
							},
							"response": [
								{
									"name": "Without token",
									"originalRequest": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"orderInfo\": \"test thanh toan\",\r\n    \"amount\": 10000,\r\n    \"bankCode\": \"\",\r\n    \"paymentMethod\": \"ALL\", \r\n    \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n    \"redirectUrl\": \"http://yourwebsite.com/redirect\",\r\n    \"extraData\": \"\",\r\n    \"clientIp\": \"103.53.171.140\",\r\n    \"signature\": \"{{payment_request_signature}}\",\r\n    \"action\": \"PAY_WITH_RETURN_TOKEN\"\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/orders/payment/bank",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"orders",
												"payment",
												"bank"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Server",
											"value": "nginx/1.10.3"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.4"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 07:12:29 GMT"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "497"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"orderId\": \"3YleueQyC\",\n    \"amount\": 10000,\n    \"paymentUrl\": \"http://localhost:8080/bank/payment/process?tran=dGlkPUFQMjIxMDU1NiZvcmRlcklkPTNZbGV1ZVF5QyZ0cz0xNjUzODk0NzQ5&sign=acca87a81cd7b0f0cefe10d923a882cb05cf2b24e7a82ec7eda1b72bbdb0d9a7\",\n    \"signature\": \"ff305c1d0a4d2311f7d0bb37fa8c8389ec648676823eb64149c0879783e4ca4c\"\n}"
								}
							]
						},
						{
							"name": "White label API",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var orderId = generateRandomString(9);\r",
											"pm.collectionVariables.set('white_label_order_id', orderId);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.orderId = orderId\r",
											"let signData = '';\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('white_label_request_signature', paymentSignature)"
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(jsonData);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"orderId\": \"{{white_label_order_id}}\",\r\n    \"orderInfo\": \"test thanh toan\",\r\n    \"amount\": 10000,\r\n    \"bankCode\": \"\",\r\n    \"paymentMethod\": \"CC\",\r\n    \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n    \"redirectUrl\": \"http://yourwebsite.com/redirect\",\r\n    \"extraData\": \"\",\r\n    \"clientIp\": \"103.53.171.140\",\r\n    \"action\": \"PAY_WITH_RETURN_TOKEN\",\r\n    \"card\": {\r\n        \"number\": \"5123450000000008\",\r\n        \"holder\": \"NGUYEN VAN A\",\r\n        \"card_month\": \"10\",\r\n        \"card_year\": \"24\",\r\n        \"cvc\": \"456\"\r\n    },\r\n    \"signature\": \"{{white_label_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1.1/payment/wl/banking",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1.1",
										"payment",
										"wl",
										"banking"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"orderId\": \"{{white_label_order_id}}\",\r\n    \"orderInfo\": \"test thanh toan\",\r\n    \"amount\": 10000,\r\n    \"bankCode\": \"\",\r\n    \"paymentMethod\": \"CC\",\r\n    \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n    \"redirectUrl\": \"http://yourwebsite.com/redirect\",\r\n    \"extraData\": \"\",\r\n    \"clientIp\": \"103.53.171.140\",\r\n    \"action\": \"PAY_WITH_RETURN_TOKEN\",\r\n    \"card\": {\r\n        \"number\": \"5123450000000008\",\r\n        \"holder\": \"NGUYEN VAN A\",\r\n        \"card_month\": \"10\",\r\n        \"card_year\": \"24\",\r\n        \"cvc\": \"456\"\r\n    },\r\n    \"signature\": \"{{white_label_request_signature}}\"\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/payment/wl/banking",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"payment",
												"wl",
												"banking"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 07:39:28 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"orderId\": \"cOeuwi6jk\",\n    \"amount\": 10000,\n    \"appotapayTransId\": \"AP221434473123\",\n    \"verifyOtpUrl\": \"https://payment.dev.appotapay.com/bank/payment/verifyOtp?transaction_id=AP221434473123&signature=1da1db1c720dd89bcd56689f346d3017388a9a8c51ea839ca91ef13075bd0774\",\n    \"signature\": \"6981d0ca6a75e322efbd68e78a68842b1500e0623ade9a14c7a9e42a6e7add10\"\n}"
								}
							]
						},
						{
							"name": "Delete token",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "DELETE",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"token\": 9395866486482725\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1.1/token/delete",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1.1",
										"token",
										"delete"
									]
								}
							},
							"response": [
								{
									"name": "Delete token",
									"originalRequest": {
										"method": "DELETE",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"token\": 9395866486482725\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/token/delete",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"token",
												"delete"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 07:43:25 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "497"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\"\n}"
								}
							]
						},
						{
							"name": "Kiểm tra trạng thái giao dịch",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"var orderId = pm.collectionVariables.get('payment_order_id');\r",
											"let signData = `orderId=${orderId}`;\r",
											"console.log(signData);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('payment_detail_request_signature', paymentSignature)"
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"// amount={amount}&apiKey={apiKey}&appotapayTransId={appotapayTransId}&bankCode={bankCode}& currency={currency}&errorCode={errorCode}&extraData={extraData}&message={message}&orderId={orderId}&partnerCode={partnerCode}&paymentMethod={paymentMethod}&paymentType={paymentType}&transactionTs={transactionTs}&status={status}\r",
											"var signArr = {\r",
											"    \"errorCode\": jsonData.errorCode,\r",
											"    \"message\": jsonData.message,\r",
											"    \"partnerCode\": jsonData.partnerCode,\r",
											"    \"apiKey\": jsonData.apiKey,\r",
											"    \"status\": jsonData.transaction.status,\r",
											"    \"amount\": jsonData.transaction.amount,\r",
											"    \"currency\": jsonData.transaction.currency,\r",
											"    \"orderId\": jsonData.transaction.orderId,\r",
											"    \"bankCode\": jsonData.transaction.bankCode,\r",
											"    \"paymentMethod\": jsonData.transaction.paymentMethod,\r",
											"    \"paymentType\": jsonData.transaction.paymentType,\r",
											"    \"appotapayTransId\": jsonData.transaction.appotapayTransId,\r",
											"    \"transactionTs\": jsonData.transaction.transactionTs,\r",
											"    \"extraData\": jsonData.transaction.extraData,\r",
											"};\r",
											"\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(signArr);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});\r",
											"pm.collectionVariables.set('appotapay_trans_id', jsonData.appotapayTransId)"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"signature\": \"{{payment_detail_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1.1/orders/transaction/bank/status",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1.1",
										"orders",
										"transaction",
										"bank",
										"status"
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"orderId\": \"{{payment_order_id}}\",\r\n    \"signature\": \"{{payment_detail_request_signature}}\"\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/orders/transaction/bank/status",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"orders",
												"transaction",
												"bank",
												"status"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 09:34:26 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "498"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"partnerCode\": \"TEST\",\n    \"apiKey\": \"oMhJpkz7K6HDcR6S\",\n    \"transaction\": {\n        \"status\": \"success\",\n        \"amount\": 10000,\n        \"currency\": \"VND\",\n        \"orderId\": \"ISH8mh9B8\",\n        \"bankCode\": \"ABBANK\",\n        \"paymentMethod\": \"ATM\",\n        \"paymentType\": \"WEB\",\n        \"appotapayTransId\": \"AP221434473986\",\n        \"transactionTs\": 1653898134,\n        \"extraData\": \"\"\n    },\n    \"signature\": \"a83dc2414285acc32baba6abc9d7bc317422f71035c6d4dfca32bdb0efa81473\"\n}"
								}
							]
						},
						{
							"name": "Danh sách giao dịch",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"//Generate Signature\r",
											"var query = {};\r",
											"pm.request.url.query.all().forEach((param) => { query[param.key] = param.value});\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(query);\r",
											"let signData = '';\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('get_transaction_list_signature', paymentSignature)"
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1.1/orders/transactions?startTime=1651373012&endTime=1653878612&status=success&paymentMethod=ATM&limit=12&page=1&signature={{get_transaction_list_signature}}",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1.1",
										"orders",
										"transactions"
									],
									"query": [
										{
											"key": "startTime",
											"value": "1651373012"
										},
										{
											"key": "endTime",
											"value": "1653878612"
										},
										{
											"key": "status",
											"value": "success"
										},
										{
											"key": "paymentMethod",
											"value": "ATM"
										},
										{
											"key": "limit",
											"value": "12"
										},
										{
											"key": "page",
											"value": "1"
										},
										{
											"key": "signature",
											"value": "{{get_transaction_list_signature}}"
										}
									]
								}
							},
							"response": [
								{
									"name": "Success",
									"originalRequest": {
										"method": "GET",
										"header": [],
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/orders/transactions?startTime=1651373012&endTime=1653878612&status=success&paymentMethod=ATM&limit=12&page=1&signature={{get_transaction_list_signature}}",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"orders",
												"transactions"
											],
											"query": [
												{
													"key": "startTime",
													"value": "1651373012"
												},
												{
													"key": "endTime",
													"value": "1653878612"
												},
												{
													"key": "status",
													"value": "success"
												},
												{
													"key": "paymentMethod",
													"value": "ATM"
												},
												{
													"key": "limit",
													"value": "12"
												},
												{
													"key": "page",
													"value": "1"
												},
												{
													"key": "signature",
													"value": "{{get_transaction_list_signature}}"
												}
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 10:04:08 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"total\": 29,\n    \"page\": 1,\n    \"transactions\": [\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 200000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22053030376292B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434466632\",\n            \"transactionTs\": 1653878605,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 80000,\n            \"currency\": \"VND\",\n            \"orderId\": \"V8ERHMN34DTHHBU75OVAHTEC\",\n            \"bankCode\": \"SAIGONBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434446320\",\n            \"transactionTs\": 1653637876,\n            \"extraData\": \"629081fac516f900355bef35\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 80000,\n            \"currency\": \"VND\",\n            \"orderId\": \"GRIKJVIEQJBJDGEHNIKB6TAY\",\n            \"bankCode\": \"SAIGONBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434445971\",\n            \"transactionTs\": 1653637199,\n            \"extraData\": \"6290800ac516f900355bef2f\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 80000,\n            \"currency\": \"VND\",\n            \"orderId\": \"K0XWDSHLNOGPKDRSH7T6LIN8\",\n            \"bankCode\": \"SAIGONBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434441029\",\n            \"transactionTs\": 1653627222,\n            \"extraData\": \"629058e903684b0035faac82\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 40000,\n            \"currency\": \"VND\",\n            \"orderId\": \"VHJS5N1AAOI7PPEEUPXJBOXB\",\n            \"bankCode\": \"SAIGONBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434440620\",\n            \"transactionTs\": 1653626388,\n            \"extraData\": \"629055dc4125300034fe117b\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 500000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22051230239982B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434287596\",\n            \"transactionTs\": 1652324587,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 100000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22051230239861B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434287474\",\n            \"transactionTs\": 1652323053,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 100000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22051130235058B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434286158\",\n            \"transactionTs\": 1652262996,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 5000000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22051030223247B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434278463\",\n            \"transactionTs\": 1652172494,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 100000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22051030222562B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434275568\",\n            \"transactionTs\": 1652167697,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 50000,\n            \"currency\": \"VND\",\n            \"orderId\": \"AP22051030222545B\",\n            \"bankCode\": \"TECHCOMBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434275493\",\n            \"transactionTs\": 1652167606,\n            \"extraData\": \"\"\n        },\n        {\n            \"errorCode\": 0,\n            \"status\": \"success\",\n            \"amount\": 1188000,\n            \"currency\": \"VND\",\n            \"orderId\": \"KDATA2205102adb5acee\",\n            \"bankCode\": \"SAIGONBANK\",\n            \"paymentMethod\": \"ATM\",\n            \"paymentType\": \"WEB\",\n            \"appotapayTransId\": \"AP221434275399\",\n            \"transactionTs\": 1652165710,\n            \"extraData\": \"\"\n        }\n    ]\n}"
								}
							]
						},
						{
							"name": "Kiểm tra thông tin token và thẻ",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v1.1/token/{{payment_order_id}}",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v1.1",
										"token",
										"{{payment_order_id}}"
									]
								}
							},
							"response": [
								{
									"name": "Failed",
									"originalRequest": {
										"method": "GET",
										"header": [],
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/token/{{payment_order_id}}",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"token",
												"{{payment_order_id}}"
											]
										}
									},
									"status": "Bad Request",
									"code": 400,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 10:05:23 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 87,\n    \"message\": \"Token không tồn tại\"\n}"
								},
								{
									"name": "Success",
									"originalRequest": {
										"method": "GET",
										"header": [],
										"url": {
											"raw": "{{payment_endpoint_url}}/api/v1.1/token/{{payment_order_id}}",
											"host": [
												"{{payment_endpoint_url}}"
											],
											"path": [
												"api",
												"v1.1",
												"token",
												"{{payment_order_id}}"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 10:16:08 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "499"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"tokenResult\": {\n        \"status\": \"active\",\n        \"token\": \"9764111040809595\",\n        \"card_name\": \"NGUYEN VAN A\",\n        \"card_number\": \"970400xxxxxx0018\",\n        \"card_date\": \"\",\n        \"card_type\": \"ATM_CARD\"\n    }\n}"
								}
							]
						}
					]
				},
				{
					"name": "v2.0",
					"item": [
						{
							"name": "Tạo order thanh toán",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var order = generateRandomString(9);\r",
											"pm.collectionVariables.set('payment_order_id', order);"
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"pm.collectionVariables.set('appotapay_trans_id', jsonData.transaction.transactionId)"
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "X-Language",
										"value": "vi",
										"type": "text"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"transaction\": {\r\n        \"amount\": 10000,\r\n        \"currency\": \"VND\",\r\n        \"bankCode\": \"\",\r\n        \"paymentMethod\": \"ALL\",\r\n        \"action\": \"PAY\"\r\n    },\r\n    \"partnerReference\": {\r\n        \"order\": {\r\n            \"id\": \"{{payment_order_id}}\",\r\n            \"info\": \"test thanh toan\",\r\n            \"extraData\": \"\"\r\n        },\r\n        \"notificationConfig\": {\r\n            \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n            \"redirectUrl\": \"http://yourwebsite.com/redirect\"\r\n        }\r\n    }\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_base_url}}/api/v2/orders/payment",
									"host": [
										"{{payment_base_url}}"
									],
									"path": [
										"api",
										"v2",
										"orders",
										"payment"
									]
								}
							},
							"response": []
						},
						{
							"name": "Kiểm tra thông tin giao dịch",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"var orderId = pm.collectionVariables.get('payment_order_id');\r",
											"let signData = `orderId=${orderId}`;\r",
											"console.log(signData);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('payment_detail_request_signature', paymentSignature)"
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"pm.collectionVariables.set('appotapay_trans_id', jsonData.transaction.transactionId)"
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [
									{
										"key": "X-Language",
										"value": "vi",
										"type": "text"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"referenceId\": \"{{payment_order_id}}\",\r\n    \"type\": \"PARTNER_ORDER_ID\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_base_url}}/api/v2/orders/transaction",
									"host": [
										"{{payment_base_url}}"
									],
									"path": [
										"api",
										"v2",
										"orders",
										"transaction"
									]
								}
							},
							"response": []
						},
						{
							"name": "Delete token",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											""
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"request": {
								"method": "DELETE",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"token\": \"9704001845460018\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_endpoint_url}}/api/v2/token/delete",
									"host": [
										"{{payment_endpoint_url}}"
									],
									"path": [
										"api",
										"v2",
										"token",
										"delete"
									]
								}
							},
							"response": [
								{
									"name": "Delete token",
									"originalRequest": {
										"method": "DELETE",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"token\": 9395866486482725\r\n}",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "https://payment.dev.appotapay.com/api/v1.1/token/delete",
											"protocol": "https",
											"host": [
												"payment",
												"dev",
												"appotapay",
												"com"
											],
											"path": [
												"api",
												"v1.1",
												"token",
												"delete"
											]
										}
									},
									"status": "OK",
									"code": 200,
									"_postman_previewlanguage": "json",
									"header": [
										{
											"key": "Date",
											"value": "Mon, 30 May 2022 07:43:25 GMT"
										},
										{
											"key": "Content-Type",
											"value": "application/json"
										},
										{
											"key": "Transfer-Encoding",
											"value": "chunked"
										},
										{
											"key": "Connection",
											"value": "keep-alive"
										},
										{
											"key": "Vary",
											"value": "Accept-Encoding"
										},
										{
											"key": "X-Powered-By",
											"value": "PHP/7.4.14"
										},
										{
											"key": "Cache-Control",
											"value": "no-cache, private"
										},
										{
											"key": "X-RateLimit-Limit",
											"value": "500"
										},
										{
											"key": "X-RateLimit-Remaining",
											"value": "497"
										},
										{
											"key": "Access-Control-Allow-Origin",
											"value": "*"
										},
										{
											"key": "X-Frame-Options",
											"value": "NEVER"
										},
										{
											"key": "X-XSS-Protection",
											"value": "1; mode=block"
										},
										{
											"key": "Strict-Transport-Security",
											"value": "max-age=15724800; includeSubDomains"
										},
										{
											"key": "Content-Encoding",
											"value": "gzip"
										}
									],
									"cookie": [],
									"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\"\n}"
								}
							]
						},
						{
							"name": "Hoàn tiền giao dịch",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var refundRefId = generateRandomString(9);\r",
											"pm.collectionVariables.set('refund_ref_id', refundRefId);"
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(jsonData);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});"
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "X-Language",
										"value": "vi",
										"type": "text"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"partnerRefId\": \"{{refund_ref_id}}\",\r\n    \"transactionId\": \"{{appotapay_trans_id}}\",\r\n    \"amount\": 10000,\r\n    \"currency\": \"VND\",\r\n    \"reason\": \"Test refund\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_base_url}}/api/v2/transaction/refund",
									"host": [
										"{{payment_base_url}}"
									],
									"path": [
										"api",
										"v2",
										"transaction",
										"refund"
									]
								}
							},
							"response": []
						},
						{
							"name": "Kiểm tra giao dịch hoàn tiền",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var order = generateRandomString(9);\r",
											"pm.collectionVariables.set('payment_order_id', order);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.orderId = order\r",
											"let signData = '';\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.environment.set('payment_request_signature', paymentSignature)"
										],
										"type": "text/javascript",
										"packages": {}
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {\r",
											"    pm.response.to.have.status(200);\r",
											"});\r",
											"pm.test(\"Error code is success\", function () {\r",
											"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
											"});\r",
											"\r",
											"var jsonData = JSON.parse(responseBody);\r",
											"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
											"function ksort(obj) {\r",
											"    var keys = Object.keys(obj).sort()\r",
											"        , sortedObj = {};\r",
											"\r",
											"    for (var i in keys) {\r",
											"        sortedObj[keys[i]] = obj[keys[i]];\r",
											"    }\r",
											"\r",
											"    return sortedObj;\r",
											"}\r",
											"signArr = ksort(jsonData);\r",
											"let signData = '';\r",
											"for (const [key, value] of Object.entries(signArr)) {\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"\r",
											"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
											"pm.test(\"Signature is valid\", function () {\r",
											"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
											"});"
										],
										"type": "text/javascript",
										"packages": {}
									}
								}
							],
							"protocolProfileBehavior": {
								"disableBodyPruning": true
							},
							"request": {
								"method": "GET",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"type\": \"PARTNER_ORDER_ID\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{payment_base_url}}/api/v2/transaction/refund/{{refund_ref_id}}",
									"host": [
										"{{payment_base_url}}"
									],
									"path": [
										"api",
										"v2",
										"transaction",
										"refund",
										"{{refund_ref_id}}"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "paypal",
					"item": [
						{
							"name": "Create order",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var order = generateRandomString(9);\r",
											"\r",
											"pm.environment.set('order_id', order);\r",
											"\r",
											"// JWT generation script adapted from\r",
											"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d\r",
											"\r",
											"var jwtSecret = pm.environment.get('secret_key') || ''\r",
											"\r",
											"// Set headers for JWT\r",
											"var header = {\r",
											"\t'typ': 'JWT',\r",
											"\t'alg': 'HS256',\r",
											"    'cty': 'appotapay-api;v=1'\r",
											"};\r",
											"\r",
											"// Prepare timestamp in seconds\r",
											"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
											"\r",
											"var data = {\r",
											"\t'iss': pm.environment.get('partner_code') || '',\r",
											"\t'api_key': pm.environment.get('api_key') || '',\r",
											"    'jti': (pm.environment.get('api_key') || '')+currentTimestamp,\r",
											"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation\r",
											"}\r",
											"\r",
											"\r",
											"function base64url(source) {\r",
											"    // Encode in classical base64\r",
											"    encodedSource = CryptoJS.enc.Base64.stringify(source)\r",
											"    \r",
											"    // Remove padding equal characters\r",
											"    encodedSource = encodedSource.replace(/=+$/, '')\r",
											"    \r",
											"    // Replace characters according to base64url specifications\r",
											"    encodedSource = encodedSource.replace(/\\+/g, '-')\r",
											"    encodedSource = encodedSource.replace(/\\//g, '_')\r",
											"    \r",
											"    return encodedSource\r",
											"}\r",
											"\r",
											"// encode header\r",
											"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))\r",
											"var encodedHeader = base64url(stringifiedHeader)\r",
											"\r",
											"// encode data\r",
											"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))\r",
											"var encodedData = base64url(stringifiedData)\r",
											"\r",
											"// build token\r",
											"var token = `${encodedHeader}.${encodedData}`\r",
											"\r",
											"// sign token\r",
											"var signature = CryptoJS.HmacSHA256(token, jwtSecret)\r",
											"signature = base64url(signature)\r",
											"var signedToken = `${token}.${signature}`\r",
											"\r",
											"pm.environment.set('jwt_token', signedToken);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.orderId = order\r",
											"let signData = '';\r",
											"console.log(Object.entries(requestBody))\r",
											"// for (let [key, value] of Object.entries(requestBody)) {\r",
											"//     if (typeof value === 'object') value = JSON.stringify(value);\r",
											"//     if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"// }\r",
											"signData = `currencyCode=${requestBody.currencyCode}&notifyUrl=${requestBody.notifyUrl}&orderId=${requestBody.orderId}&redirectUrl=${requestBody.redirectUrl}&totalAmount=${requestBody.totalAmount}`;\r",
											"console.log(signData)\r",
											"const payemntSignature = CryptoJS.HmacSHA256(signData, jwtSecret).toString()\r",
											"pm.environment.set('request_signature', payemntSignature)"
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "test",
									"script": {
										"exec": [
											"var jsonData = JSON.parse(responseBody);\r",
											"pm.environment.set('appota_tran_id', jsonData.data.appotaTransId);"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "X-APPOTAPAY-AUTH",
										"value": "{{jwt_token}}",
										"type": "text"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"totalAmount\":\"180.10\",\r\n  \"orderId\":\"{{order_id}}\",\r\n  \"redirectUrl\":\"https://db79-103-53-170-145.ap.ngrok.io/api/callback1\",\r\n  \"notifyUrl\":\"https://db79-103-53-170-145.ap.ngrok.io/api/callback1\",\r\n  \"currencyCode\":\"USD\",\r\n  \"signature\": \"{{request_signature}}\"\r\n}\r\n",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{api_url}}/api/paypal/v1/create-order-appota",
									"host": [
										"{{api_url}}"
									],
									"path": [
										"api",
										"paypal",
										"v1",
										"create-order-appota"
									]
								}
							},
							"response": []
						},
						{
							"name": "Get order detail",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"// JWT generation script adapted from\r",
											"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d\r",
											"\r",
											"var jwtSecret = pm.environment.get('secret_key') || ''\r",
											"\r",
											"// Set headers for JWT\r",
											"var header = {\r",
											"\t'typ': 'JWT',\r",
											"\t'alg': 'HS256',\r",
											"    'cty': 'appotapay-api;v=1'\r",
											"};\r",
											"\r",
											"// Prepare timestamp in seconds\r",
											"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
											"\r",
											"var data = {\r",
											"\t'iss': pm.environment.get('partner_code') || '',\r",
											"\t'api_key': pm.environment.get('api_key') || '',\r",
											"    'jti': (pm.environment.get('api_key') || '')+currentTimestamp,\r",
											"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation\r",
											"}\r",
											"\r",
											"\r",
											"function base64url(source) {\r",
											"    // Encode in classical base64\r",
											"    encodedSource = CryptoJS.enc.Base64.stringify(source)\r",
											"    \r",
											"    // Remove padding equal characters\r",
											"    encodedSource = encodedSource.replace(/=+$/, '')\r",
											"    \r",
											"    // Replace characters according to base64url specifications\r",
											"    encodedSource = encodedSource.replace(/\\+/g, '-')\r",
											"    encodedSource = encodedSource.replace(/\\//g, '_')\r",
											"    \r",
											"    return encodedSource\r",
											"}\r",
											"\r",
											"// encode header\r",
											"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))\r",
											"var encodedHeader = base64url(stringifiedHeader)\r",
											"\r",
											"// encode data\r",
											"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))\r",
											"var encodedData = base64url(stringifiedData)\r",
											"\r",
											"// build token\r",
											"var token = `${encodedHeader}.${encodedData}`\r",
											"\r",
											"// sign token\r",
											"var signature = CryptoJS.HmacSHA256(token, jwtSecret)\r",
											"signature = base64url(signature)\r",
											"var signedToken = `${token}.${signature}`\r",
											"\r",
											"pm.environment.set('jwt_token', signedToken);\r",
											"\r",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "GET",
								"header": [
									{
										"key": "X-APPOTAPAY-AUTH",
										"value": "{{jwt_token}}",
										"type": "text"
									}
								],
								"url": {
									"raw": "{{api_url}}/api/paypal/v1/detail-order?orderId={{order_id}}",
									"host": [
										"{{api_url}}"
									],
									"path": [
										"api",
										"paypal",
										"v1",
										"detail-order"
									],
									"query": [
										{
											"key": "orderId",
											"value": "{{order_id}}"
										}
									]
								}
							},
							"response": []
						},
						{
							"name": "Refund Order",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"var order = generateRandomString(9);\r",
											"\r",
											"pm.environment.set('refund_id', order);\r",
											"\r",
											"// JWT generation script adapted from\r",
											"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d\r",
											"\r",
											"var jwtSecret = pm.environment.get('secret_key') || ''\r",
											"\r",
											"// Set headers for JWT\r",
											"var header = {\r",
											"\t'typ': 'JWT',\r",
											"\t'alg': 'HS256',\r",
											"    'cty': 'appotapay-api;v=1'\r",
											"};\r",
											"\r",
											"// Prepare timestamp in seconds\r",
											"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
											"\r",
											"var data = {\r",
											"\t'iss': pm.environment.get('partner_code') || '',\r",
											"\t'api_key': pm.environment.get('api_key') || '',\r",
											"    'jti': (pm.environment.get('api_key') || '')+currentTimestamp,\r",
											"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation\r",
											"}\r",
											"\r",
											"\r",
											"function base64url(source) {\r",
											"    // Encode in classical base64\r",
											"    encodedSource = CryptoJS.enc.Base64.stringify(source)\r",
											"    \r",
											"    // Remove padding equal characters\r",
											"    encodedSource = encodedSource.replace(/=+$/, '')\r",
											"    \r",
											"    // Replace characters according to base64url specifications\r",
											"    encodedSource = encodedSource.replace(/\\+/g, '-')\r",
											"    encodedSource = encodedSource.replace(/\\//g, '_')\r",
											"    \r",
											"    return encodedSource\r",
											"}\r",
											"\r",
											"// encode header\r",
											"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))\r",
											"var encodedHeader = base64url(stringifiedHeader)\r",
											"\r",
											"// encode data\r",
											"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))\r",
											"var encodedData = base64url(stringifiedData)\r",
											"\r",
											"// build token\r",
											"var token = `${encodedHeader}.${encodedData}`\r",
											"\r",
											"// sign token\r",
											"var signature = CryptoJS.HmacSHA256(token, jwtSecret)\r",
											"signature = base64url(signature)\r",
											"var signedToken = `${token}.${signature}`\r",
											"\r",
											"pm.environment.set('jwt_token', signedToken);\r",
											"\r",
											"//Generate Signature\r",
											"var requestBody = JSON.parse(request['data']);\r",
											"\r",
											"function ksort(obj){\r",
											"  var keys = Object.keys(obj).sort()\r",
											"    , sortedObj = {};\r",
											"\r",
											"  for(var i in keys) {\r",
											"    sortedObj[keys[i]] = obj[keys[i]];\r",
											"  }\r",
											"\r",
											"  return sortedObj;\r",
											"}\r",
											"requestBody = ksort(requestBody);\r",
											"requestBody.refundId = order\r",
											"requestBody.appotaTransId = pm.environment.get('appota_tran_id')\r",
											"let signData = '';\r",
											"console.log(Object.entries(requestBody))\r",
											"for (let [key, value] of Object.entries(requestBody)) {\r",
											"    if (typeof value === 'object') value = JSON.stringify(value);\r",
											"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
											"}\r",
											"signData = signData.substring(1);\r",
											"console.log(signData)\r",
											"const payemntSignature = CryptoJS.HmacSHA256(signData, jwtSecret).toString()\r",
											"pm.environment.set('request_signature', payemntSignature)"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "X-APPOTAPAY-AUTH",
										"value": "{{jwt_token}}",
										"type": "text"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"refundId\":\"{{refund_id}}\",\r\n  \"appotaTransId\": \"{{appota_tran_id}}\",\r\n  \"amount\": \"100.10\",\r\n  \"reason\": \"Test vui vui\",\r\n  \"signature\": \"{{request_signature}}\"\r\n}\r\n",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{api_url}}/api/paypal/v1/refund-order-appota",
									"host": [
										"{{api_url}}"
									],
									"path": [
										"api",
										"paypal",
										"v1",
										"refund-order-appota"
									]
								}
							},
							"response": []
						},
						{
							"name": "Get refund detail",
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"function generateRandomString(length) {\r",
											"    var text = '';\r",
											"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
											"    for (var i = 0; i < length; i++) {\r",
											"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
											"    }\r",
											"    return text;\r",
											"}\r",
											"// JWT generation script adapted from\r",
											"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d\r",
											"\r",
											"var jwtSecret = pm.environment.get('secret_key') || ''\r",
											"\r",
											"// Set headers for JWT\r",
											"var header = {\r",
											"\t'typ': 'JWT',\r",
											"\t'alg': 'HS256',\r",
											"    'cty': 'appotapay-api;v=1'\r",
											"};\r",
											"\r",
											"// Prepare timestamp in seconds\r",
											"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
											"\r",
											"var data = {\r",
											"\t'iss': pm.environment.get('partner_code') || '',\r",
											"\t'api_key': pm.environment.get('api_key') || '',\r",
											"    'jti': (pm.environment.get('api_key') || '')+currentTimestamp,\r",
											"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation\r",
											"}\r",
											"\r",
											"\r",
											"function base64url(source) {\r",
											"    // Encode in classical base64\r",
											"    encodedSource = CryptoJS.enc.Base64.stringify(source)\r",
											"    \r",
											"    // Remove padding equal characters\r",
											"    encodedSource = encodedSource.replace(/=+$/, '')\r",
											"    \r",
											"    // Replace characters according to base64url specifications\r",
											"    encodedSource = encodedSource.replace(/\\+/g, '-')\r",
											"    encodedSource = encodedSource.replace(/\\//g, '_')\r",
											"    \r",
											"    return encodedSource\r",
											"}\r",
											"\r",
											"// encode header\r",
											"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))\r",
											"var encodedHeader = base64url(stringifiedHeader)\r",
											"\r",
											"// encode data\r",
											"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))\r",
											"var encodedData = base64url(stringifiedData)\r",
											"\r",
											"// build token\r",
											"var token = `${encodedHeader}.${encodedData}`\r",
											"\r",
											"// sign token\r",
											"var signature = CryptoJS.HmacSHA256(token, jwtSecret)\r",
											"signature = base64url(signature)\r",
											"var signedToken = `${token}.${signature}`\r",
											"\r",
											"pm.environment.set('jwt_token', signedToken);\r",
											"\r",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "GET",
								"header": [
									{
										"key": "X-APPOTAPAY-AUTH",
										"value": "{{jwt_token}}",
										"type": "text"
									}
								],
								"url": {
									"raw": "{{api_url}}/api/paypal/v1/detail-order-refund?refundId={{refund_id}}",
									"host": [
										"{{api_url}}"
									],
									"path": [
										"api",
										"paypal",
										"v1",
										"detail-order-refund"
									],
									"query": [
										{
											"key": "refundId",
											"value": "{{refund_id}}"
										}
									]
								}
							},
							"response": []
						}
					]
				}
			]
		},
		{
			"name": "Thanh toán thẻ/ tài khoản nội địa",
			"item": [
				{
					"name": "Tạo order thanh toán - Merchant hosted",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var order = generateRandomString(9);\r",
									"pm.collectionVariables.set('payment_order_id', order);"
								],
								"type": "text/javascript",
								"packages": {}
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj) {\r",
									"    var keys = Object.keys(obj).sort()\r",
									"        , sortedObj = {};\r",
									"\r",
									"    for (var i in keys) {\r",
									"        sortedObj[keys[i]] = obj[keys[i]];\r",
									"    }\r",
									"\r",
									"    return sortedObj;\r",
									"}\r",
									"signArr = ksort(jsonData);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.test(\"Signature is valid\", function () {\r",
									"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
									"});"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "X-Language",
								"value": "vi",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"transaction\": {\r\n        \"amount\": 10000,\r\n        \"currency\": \"VND\",\r\n        \"bankCode\": \"VPBANK\",\r\n        \"paymentMethod\": \"ATM\",\r\n        \"action\": \"PAY\"\r\n    },\r\n    \"sourceOfFunds\": {\r\n        \"type\": \"card\",\r\n        \"card\": {\r\n            \"cardNumber\": \"9704000000000018\",\r\n            \"cardHolderName\": \"NGUYEN VAN A\",\r\n            \"cardMonth\": \"03\",\r\n            \"cardYear\": \"07\"\r\n        }\r\n    },\r\n    \"partnerReference\": {\r\n        \"order\": {\r\n            \"id\": \"{{payment_order_id}}\",\r\n            \"info\": \"đơn hàng thanh toán\",\r\n            \"extraData\": \"\"\r\n        },\r\n        \"notificationConfig\": {\r\n            \"notifyUrl\": \"http://yourwebsite.com/ipn\",\r\n            \"redirectUrl\": \"http://yourwebsite.com/redirect\"\r\n        }\r\n    }\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_endpoint_url}}/api/v2/orders/create-payment",
							"host": [
								"{{payment_endpoint_url}}"
							],
							"path": [
								"api",
								"v2",
								"orders",
								"create-payment"
							]
						}
					},
					"response": []
				}
			]
		},
		{
			"name": "Thu hộ",
			"item": [
				{
					"name": "1. Tạo tài khoản thu hộ",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"// Generate BillCode (Random unique string)\r",
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var billCode = generateRandomString(9);\r",
									"pm.collectionVariables.set('bill_code', billCode);\r",
									"\r",
									"// Set BillExpiryTime\r",
									"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
									"var billExpiryTime = currentTimestamp + 365 * 24 * 60 * 60 // Expired after 365 days\r",
									"pm.collectionVariables.set('bill_expiry_time', billExpiryTime)\r",
									"\r",
									"//Generate Signature\r",
									"\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"requestBody.billCode = billCode\r",
									"requestBody.billExpiryTime = billExpiryTime\r",
									"let signData = '';\r",
									"console.log(Object.entries(requestBody))\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString() // Using HMAC SHA256 with secret key\r",
									"pm.collectionVariables.set('request_signature', paymentSignature)\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"// signData = billCode + errorCode + json_encode(payment)\r",
									"var signArr = {\r",
									"    \"billCode\": jsonData.billCode,\r",
									"    \"errorCode\": jsonData.errorCode,\r",
									"    \"payment\": JSON.stringify(jsonData.payment)\r",
									"};\r",
									"function ksort(obj) {\r",
									"    var keys = Object.keys(obj).sort()\r",
									"        , sortedObj = {};\r",
									"\r",
									"    for (var i in keys) {\r",
									"        sortedObj[keys[i]] = obj[keys[i]];\r",
									"    }\r",
									"\r",
									"    return sortedObj;\r",
									"}\r",
									"signArr = ksort(signArr);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.test(\"Signature is valid\", function () {\r",
									"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
									"});\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"billCode\": \"{{bill_code}}\",\r\n    \"billInfo\": \"Tài khoản thu hộ\",\r\n    \"billExpiryTime\": \"{{bill_expiry_time}}\",\r\n    \"customerName\": \"APPOTAPAY\",\r\n    \"amount\": 10000,\r\n    \"paymentCondition\": \"NO\",\r\n    \"bankCode\": \"APPOTA_TEST\",\r\n    \"notifyUrl\": \"https://appotapay.com\",\r\n    \"signature\": \"{{request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/ebill/create",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"ebill",
								"create"
							]
						},
						"description": "API được sử dụng để tạo hóa đơn thanh toán"
					},
					"response": []
				},
				{
					"name": "2. Danh sách GD",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"var now = new Date();\r",
									"var startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());\r",
									"var endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()+1);\r",
									"pm.collectionVariables.set('start_of_day', startOfDay/1000);\r",
									"pm.collectionVariables.set('end_of_day', (endOfDay/1000)-1);"
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"jsonData = pm.response.json()\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(jsonData.errorCode).to.eql(0);\r",
									"});\r",
									"pm.test(\"Total page is number\", function () {\r",
									"    pm.expect(jsonData.total).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"Page is number\", function () {\r",
									"    pm.expect(jsonData.page).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"List transaction is array\", function () {\r",
									"    pm.expect(jsonData.transactions).to.be.an(\"array\");\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/ebill/transactions?startTime={{start_of_day}}&endTime={{end_of_day}}&billCode={{bill_code}}&limit=10&page=1",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"ebill",
								"transactions"
							],
							"query": [
								{
									"key": "startTime",
									"value": "{{start_of_day}}",
									"description": "Required"
								},
								{
									"key": "endTime",
									"value": "{{end_of_day}}",
									"description": "Required"
								},
								{
									"key": "billCode",
									"value": "{{bill_code}}",
									"description": "Nullable"
								},
								{
									"key": "limit",
									"value": "10",
									"description": "Nullable"
								},
								{
									"key": "page",
									"value": "1",
									"description": "Nullable"
								}
							]
						},
						"description": "API được chỉ định để xem danh sách giao dịch"
					},
					"response": []
				},
				{
					"name": "3. Danh sách GD theo TK",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"jsonData = pm.response.json()\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(jsonData.errorCode).to.eql(0);\r",
									"});\r",
									"pm.test(\"Amount is int value\", function () {\r",
									"    pm.expect(jsonData.amount).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"Paid amount is int value\", function () {\r",
									"    pm.expect(jsonData.paidAmount).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"Expiry time is int value\", function () {\r",
									"    pm.expect(jsonData.billExpiryTime).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"List transaction is array\", function () {\r",
									"    pm.expect(jsonData.transactions).to.be.an(\"array\");\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/ebill/{{bill_code}}/transactions",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"ebill",
								"{{bill_code}}",
								"transactions"
							]
						},
						"description": "API được chỉ định để lấy danh sách giao dịch của 1 hoá đơn"
					},
					"response": []
				},
				{
					"name": "4. Chi tiết giao dịch",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"jsonData = pm.response.json()\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(jsonData.errorCode).to.eql(0);\r",
									"});\r",
									"pm.test(\"Amount is number\", function () {\r",
									"    pm.expect(jsonData.amount).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"Paid amount is number\", function () {\r",
									"    pm.expect(jsonData.paidAmount).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"Bill Expiry Time is number\", function () {\r",
									"    pm.expect(jsonData.billExpiryTime).to.be.a(\"number\");\r",
									"});\r",
									"pm.test(\"Payment is object value\", function () {\r",
									"    pm.expect(jsonData.payment).to.be.an(\"object\");\r",
									"});\r",
									"pm.test(\"Payment object has bank accounts\", function () {\r",
									"    pm.expect(jsonData.payment).to.have.property('bankAccounts');\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/ebill/detail/{{bill_code}}",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"ebill",
								"detail",
								"{{bill_code}}"
							]
						},
						"description": "API được chỉ định để kiểm tra chi tiết đơn hàng"
					},
					"response": []
				},
				{
					"name": "Huỷ tài khoản thu hộ",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"var requestBody = request['data'];\r",
									"\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"\r",
									"let signData = '';\r",
									"console.log(Object.entries(requestBody))\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const paymentSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString() // Using HMAC SHA256 with secret key\r",
									"pm.collectionVariables.set('request_signature', paymentSignature)\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "formdata",
							"formdata": [
								{
									"key": "accountNo",
									"value": "902000668594",
									"description": "Your account no from api create va",
									"type": "text"
								},
								{
									"key": "billCode",
									"value": "JtwXxvdXz",
									"description": "Your bill code from api create va",
									"type": "text"
								},
								{
									"key": "partnerRefId",
									"value": "111211222",
									"description": "Your number request id - gen random & can check in future, please save your number request",
									"type": "text"
								},
								{
									"key": "signature",
									"value": "{{request_signature}}",
									"type": "text"
								}
							]
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/ebill/close",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"ebill",
								"close"
							]
						},
						"description": "API được sử dụng để chuyển tiền tới tài khoản ngân hàng"
					},
					"response": []
				}
			]
		},
		{
			"name": "Chi hộ",
			"item": [
				{
					"name": "Tạo GD chi",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var transferPaymentId = generateRandomString(9);\r",
									"pm.collectionVariables.set('transfer_payment_id', transferPaymentId);\r",
									"\r",
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"requestBody.partnerRefId = transferPaymentId\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const transferSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.collectionVariables.set('transfer_request_signature', transferSignature)\r",
									"\r",
									"\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"// signData = billCode + errorCode + json_encode(payment)\r",
									"var signArr = {\r",
									"    \"amount\": jsonData.transaction.amount,\r",
									"    \"appotapayTransId\": jsonData.transaction.appotapayTransId,\r",
									"    \"errorCode\": jsonData.errorCode,\r",
									"    \"time\": jsonData.transaction.time,\r",
									"    \"transferAmount\": jsonData.transaction.transferAmount,\r",
									"};\r",
									"function ksort(obj) {\r",
									"    var keys = Object.keys(obj).sort()\r",
									"        , sortedObj = {};\r",
									"\r",
									"    for (var i in keys) {\r",
									"        sortedObj[keys[i]] = obj[keys[i]];\r",
									"    }\r",
									"\r",
									"    return sortedObj;\r",
									"}\r",
									"signArr = ksort(signArr);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.test(\"Signature is valid\", function () {\r",
									"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
									"});\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"bankCode\": \"APPOTA_TEST\",\r\n    \"accountNo\": \"9704000000000018\",\r\n    \"accountType\": \"card\",\r\n    \"amount\": \"10000\",\r\n    \"accountName\": \"AP APPOTAPAY\",\r\n    \"partnerRefId\": \"{{transfer_payment_id}}\",\r\n    \"message\": \"Test transfer payment\",\r\n    \"feeType\": \"payer\",\r\n    \"signature\": \"{{transfer_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/transfer/make",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"transfer",
								"make"
							]
						},
						"description": "API được sử dụng để chuyển tiền tới tài khoản ngân hàng"
					},
					"response": [
						{
							"name": "SUCCESS",
							"originalRequest": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"bankCode\": \"APPOTA_TEST\",\r\n    \"accountNo\": \"9704000000000018\",\r\n    \"accountType\": \"card\",\r\n    \"amount\": \"10000\",\r\n    \"accountName\": \"AP APPOTAPAY\",\r\n    \"partnerRefId\": \"{{transfer_payment_id}}\",\r\n    \"message\": \"Test transfer payment\",\r\n    \"feeType\": \"payer\",\r\n    \"signature\": \"{{transfer_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{ebill_base_url}}/api/v1/service/transfer/make",
									"host": [
										"{{ebill_base_url}}"
									],
									"path": [
										"api",
										"v1",
										"service",
										"transfer",
										"make"
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Server",
									"value": "nginx/1.10.3"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.4.4"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "Date",
									"value": "Thu, 26 May 2022 04:46:11 GMT"
								},
								{
									"key": "X-RateLimit-Limit",
									"value": "500"
								},
								{
									"key": "X-RateLimit-Remaining",
									"value": "499"
								}
							],
							"cookie": [],
							"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"transaction\": {\n        \"appotapayTransId\": \"01G3ZAZF26CTKVVQ7BDVX4KN7D\",\n        \"amount\": 10000,\n        \"transferAmount\": 10000,\n        \"time\": \"26-05-2022 11:46:11\"\n    },\n    \"account\": {\n        \"balance\": 22468101\n    },\n    \"signature\": \"cb6633197f0763e0b1a9f229a855cbb7e0bcdaa517057ca2f42f9d926949172b\"\n}"
						},
						{
							"name": "PENDING",
							"originalRequest": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"bankCode\": \"APPOTA_TEST\",\r\n    \"accountNo\": \"888812341234\",\r\n    \"accountType\": \"card\",\r\n    \"amount\": \"10000\",\r\n    \"accountName\": \"AP APPOTAPAY\",\r\n    \"partnerRefId\": \"{{transfer_payment_id}}\",\r\n    \"message\": \"Test transfer payment\",\r\n    \"feeType\": \"payer\",\r\n    \"signature\": \"{{transfer_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{ebill_base_url}}/api/v1/service/transfer/make",
									"host": [
										"{{ebill_base_url}}"
									],
									"path": [
										"api",
										"v1",
										"service",
										"transfer",
										"make"
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Server",
									"value": "nginx/1.10.3"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.4.4"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "Date",
									"value": "Thu, 26 May 2022 04:46:39 GMT"
								},
								{
									"key": "X-RateLimit-Limit",
									"value": "500"
								},
								{
									"key": "X-RateLimit-Remaining",
									"value": "498"
								}
							],
							"cookie": [],
							"body": "{\n    \"errorCode\": 35,\n    \"message\": \"Giao dịch đang chờ xử lý vui lòng kiểm tra lại sau\"\n}"
						}
					]
				},
				{
					"name": "Kiểm tra trạng thái giao dịch",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"jsonData = pm.response.json()\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(jsonData.errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/transfer/transaction/{{transfer_payment_id}}",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"transfer",
								"transaction",
								"{{transfer_payment_id}}"
							]
						},
						"description": "API được chỉ định để kiểm tra trạng thái giao dịch"
					},
					"response": []
				},
				{
					"name": "Lấy thông tin tài khoản",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var getAccountInfoRequestId = generateRandomString(9);\r",
									"pm.collectionVariables.set('get_account_info_request_id', getAccountInfoRequestId);\r",
									"\r",
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"requestBody.partnerRefId = getAccountInfoRequestId\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const transferSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.collectionVariables.set('get_account_info_request_signature', transferSignature)\r",
									"\r",
									"\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"jsonData = pm.response.json()\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(jsonData.errorCode).to.eql(0);\r",
									"});\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"// signData = billCode + errorCode + json_encode(payment)\r",
									"var signArr = {\r",
									"    \"accountName\": jsonData.accountInfo.accountName,\r",
									"    \"accountNo\": jsonData.accountInfo.accountNo,\r",
									"    \"errorCode\": jsonData.errorCode,\r",
									"};\r",
									"function ksort(obj) {\r",
									"    var keys = Object.keys(obj).sort()\r",
									"        , sortedObj = {};\r",
									"\r",
									"    for (var i in keys) {\r",
									"        sortedObj[keys[i]] = obj[keys[i]];\r",
									"    }\r",
									"\r",
									"    return sortedObj;\r",
									"}\r",
									"signArr = ksort(signArr);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.test(\"Signature is valid\", function () {\r",
									"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"bankCode\": \"TPBANK\",\r\n    \"accountNo\": \"9704000000000018\",\r\n    \"accountType\": \"card\",\r\n    \"partnerRefId\":\"{{get_account_info_request_id}}\",\r\n    \"signature\": \"{{get_account_info_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/transfer/bank/account/info",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"transfer",
								"bank",
								"account",
								"info"
							]
						},
						"description": "API được chỉ định để kiểm tra thông tin tài khoản"
					},
					"response": []
				},
				{
					"name": "Truy vấn số dư tài khoản",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"jsonData = pm.response.json()\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(jsonData.errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"protocolProfileBehavior": {
						"disableBodyPruning": true
					},
					"request": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "formdata",
							"formdata": []
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/accounts/balance",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"accounts",
								"balance"
							]
						},
						"description": "API được sử dụng để kiểm tra số dư tài khoản đối tác"
					},
					"response": []
				}
			]
		},
		{
			"name": "Thanh toán hóa đơn",
			"item": [
				{
					"name": "Truy vấn thông tin hoá đơn",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"pm.collectionVariables.set(\"e_bill_detail\", JSON.stringify(jsonData.billDetail))\r",
									"pm.collectionVariables.set(\"e_bill_amount\", jsonData.billDetail[0].amount)"
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var billRequestId = generateRandomString(9);\r",
									"pm.collectionVariables.set('bill_request_id', billRequestId);\r",
									"\r",
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"requestBody.partnerRefId = billRequestId\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const billRequestSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.collectionVariables.set('bill_request_signature', billRequestSignature)\r",
									"\r",
									"\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"partnerRefId\": \"{{bill_request_id}}\",\r\n    \"billCode\": \"PD12121\",\r\n    \"serviceCode\": \"EVN\",\r\n    \"signature\": \"{{bill_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/bill/check",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"bill",
								"check"
							]
						},
						"description": "API được sử dụng để truy vấn thông tin hoá đơn"
					},
					"response": []
				},
				{
					"name": "Thanh toán hoá đơn",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"var eBillRequestId = pm.collectionVariables.get('bill_request_id')\r",
									"//Generate Signature\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"var billDetail = pm.collectionVariables.get('e_bill_detail')\r",
									"var signDataArr = {\r",
									"    \"amount\": pm.collectionVariables.get('e_bill_amount'),\r",
									"    \"billCode\": \"BILL_SUCCESS\",\r",
									"    \"billDetail\": billDetail,\r",
									"    \"partnerRefId\": eBillRequestId,\r",
									"    \"serviceCode\": \"EVN\",\r",
									"};\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"signDataArr = ksort(signDataArr);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signDataArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"console.log(signData);\r",
									"const eBillRequestSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.collectionVariables.set('e_bill_payment_request_signature', eBillRequestSignature)\r",
									"pm.collectionVariables.set('e_bill_detail',JSON.stringify(billDetail))"
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"// signData = amount + appotapayTransId + billAmount + errorCode + time\r",
									"var signArr = {\r",
									"    \"amount\": jsonData.transaction.amount,\r",
									"    \"appotapayTransId\": jsonData.transaction.appotapayTransId,\r",
									"    \"errorCode\": jsonData.errorCode,\r",
									"    \"time\": jsonData.transaction.time,\r",
									"    \"billAmount\": jsonData.transaction.billAmount,\r",
									"};\r",
									"function ksort(obj) {\r",
									"    var keys = Object.keys(obj).sort()\r",
									"        , sortedObj = {};\r",
									"\r",
									"    for (var i in keys) {\r",
									"        sortedObj[keys[i]] = obj[keys[i]];\r",
									"    }\r",
									"\r",
									"    return sortedObj;\r",
									"}\r",
									"signArr = ksort(signArr);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.test(\"Signature is valid\", function () {\r",
									"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
									"});\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"protocolProfileBehavior": {
						"disabledSystemHeaders": {}
					},
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"amount\": {{e_bill_amount}},\n    \"billDetail\": {{e_bill_detail}},\n    \"partnerRefId\": \"{{bill_request_id}}\",\n    \"billCode\": \"BILL_SUCCESS\",\n    \"serviceCode\": \"EVN\",\n    \"signature\": \"{{e_bill_payment_request_signature}}\"\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/bill/pay",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"bill",
								"pay"
							]
						},
						"description": "API được sử dụng để thanh toán hoá đơn"
					},
					"response": [
						{
							"name": "SUCCESS",
							"originalRequest": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\n    \"amount\": {{e_bill_amount}},\n    \"billDetail\": {{e_bill_detail}},\n    \"partnerRefId\": \"{{bill_request_id}}\",\n    \"billCode\": \"BILL_SUCCESS\", // BILL_SUCCESS, BILL_FAIL, BILL_PENDING\n    \"serviceCode\": \"EVN\",\n    \"signature\": \"{{e_bill_payment_request_signature}}\"\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{ebill_base_url}}/api/v1/service/bill/pay",
									"host": [
										"{{ebill_base_url}}"
									],
									"path": [
										"api",
										"v1",
										"service",
										"bill",
										"pay"
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Server",
									"value": "nginx/1.10.3"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.4.4"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "Date",
									"value": "Thu, 26 May 2022 04:35:04 GMT"
								},
								{
									"key": "X-RateLimit-Limit",
									"value": "500"
								},
								{
									"key": "X-RateLimit-Remaining",
									"value": "498"
								}
							],
							"cookie": [],
							"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"billDetail\": [\n        {\n            \"billNumber\": \"H6kfdgnUlU0OvHq2\",\n            \"period\": \"08/2099\",\n            \"amount\": 100000,\n            \"billCreated\": \"\",\n            \"billExpiry\": \"\",\n            \"billType\": \"\",\n            \"billOtherInfo\": \"\",\n            \"isPartialPaymentAllowed\": false,\n            \"extraInfo\": \"\"\n        }\n    ],\n    \"transaction\": {\n        \"appotapayTransId\": \"01G3ZAB25BHC6AJAWHR32Q45D9\",\n        \"amount\": 100000,\n        \"billAmount\": 100000,\n        \"time\": \"26-05-2022 11:35:04\"\n    },\n    \"account\": {\n        \"balance\": 22531101\n    },\n    \"signature\": \"defa6a586e49786aa08fedfcc663213ee2ef5e87050859c05f0da9d3db049be4\"\n}"
						}
					]
				},
				{
					"name": "Kiểm tra trạng thái giao dịch",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/bill/transaction/{{bill_request_id}}",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"bill",
								"transaction",
								"{{bill_request_id}}"
							]
						},
						"description": "API được sử dụng để kiểm tra trạng thái giao dịch"
					},
					"response": []
				},
				{
					"name": "Truy vấn số dư tài khoản",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/accounts/balance",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"accounts",
								"balance"
							]
						},
						"description": "API được sử dụng để kiểm tra số dư tài khoản đối tác"
					},
					"response": []
				}
			]
		},
		{
			"name": "Mua mã thẻ",
			"item": [
				{
					"name": "Mua mã thẻ",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var shopCardRequestId = generateRandomString(9);\r",
									"pm.collectionVariables.set('shop_card_request_id', shopCardRequestId);\r",
									"\r",
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"requestBody.partnerRefId = shopCardRequestId\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const shopCardRequestSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.collectionVariables.set('shop_card_request_signature', shopCardRequestSignature)\r",
									"\r",
									"\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"partnerRefId\": \"{{shop_card_request_id}}\",\r\n    \"productCode\": \"AC10\",\r\n    \"quantity\": 1,\r\n    \"signature\": \"{{shop_card_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/shopcard/buy",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"shopcard",
								"buy"
							]
						},
						"description": "API được sử dụng để mua mã thẻ"
					},
					"response": []
				},
				{
					"name": "Kiểm tra trạng thái giao dịch",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/shopcard/transaction/{{shop_card_request_id}}",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"shopcard",
								"transaction",
								"{{shop_card_request_id}}"
							]
						},
						"description": "API được sử dụng để kiểm tra trạng thái giao dịch"
					},
					"response": []
				},
				{
					"name": "Truy vấn số dư tài khoản",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/accounts/balance",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"accounts",
								"balance"
							]
						},
						"description": "API được sử dụng để kiểm tra số dư tài khoản đối tác"
					},
					"response": []
				}
			]
		},
		{
			"name": "Nạp tiền điện thoại",
			"item": [
				{
					"name": "Nạp tiền điện thoại",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var mobileTopupRequestId = generateRandomString(9);\r",
									"pm.collectionVariables.set('mobile_topup_request_id', mobileTopupRequestId);\r",
									"\r",
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"function ksort(obj){\r",
									"  var keys = Object.keys(obj).sort()\r",
									"    , sortedObj = {};\r",
									"\r",
									"  for(var i in keys) {\r",
									"    sortedObj[keys[i]] = obj[keys[i]];\r",
									"  }\r",
									"\r",
									"  return sortedObj;\r",
									"}\r",
									"requestBody = ksort(requestBody);\r",
									"requestBody.partnerRefId = mobileTopupRequestId\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(requestBody)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"const mobileTopupRequestSignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.collectionVariables.set('mobile_topup_request_signature', mobileTopupRequestSignature)\r",
									"\r",
									"\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('secret_key') || '';\r",
									"// signData = amount + appotapayTransId + errorCode + phoneNumber + time + topupAmount\r",
									"var signArr = {\r",
									"    \"amount\": jsonData.transaction.amount,\r",
									"    \"appotapayTransId\": jsonData.transaction.appotapayTransId,\r",
									"    \"errorCode\": jsonData.errorCode,\r",
									"    \"phoneNumber\": jsonData.transaction.phoneNumber,\r",
									"    \"time\": jsonData.transaction.time,\r",
									"    \"topupAmount\": jsonData.transaction.topupAmount,\r",
									"};\r",
									"function ksort(obj) {\r",
									"    var keys = Object.keys(obj).sort()\r",
									"        , sortedObj = {};\r",
									"\r",
									"    for (var i in keys) {\r",
									"        sortedObj[keys[i]] = obj[keys[i]];\r",
									"    }\r",
									"\r",
									"    return sortedObj;\r",
									"}\r",
									"signArr = ksort(signArr);\r",
									"let signData = '';\r",
									"for (const [key, value] of Object.entries(signArr)) {\r",
									"    if (key !== 'signature') signData += `&${key}=${value}`;\r",
									"}\r",
									"signData = signData.substring(1);\r",
									"\r",
									"var verifySignature = CryptoJS.HmacSHA256(signData, partnerSecretKey).toString()\r",
									"pm.test(\"Signature is valid\", function () {\r",
									"    pm.expect(pm.response.json().signature).to.eql(verifySignature);\r",
									"});\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"partnerRefId\": \"{{mobile_topup_request_id}}\",\r\n    \"telco\": \"viettel\",\r\n    \"telcoServiceType\": \"prepaid\",\r\n    \"phoneNumber\": \"0866123456\", \r\n    \"amount\": \"100000\",\r\n    \"signature\": \"{{mobile_topup_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/topup/charging",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"topup",
								"charging"
							]
						},
						"description": "API được sử dụng để nạp tiền điện thoại trực tiếp"
					},
					"response": [
						{
							"name": "SUCCESS",
							"originalRequest": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"partnerRefId\": \"{{mobile_topup_request_id}}\",\r\n    \"telco\": \"viettel\",\r\n    \"telcoServiceType\": \"prepaid\",\r\n    \"phoneNumber\": \"0866123456\", // viettel => 0866123456, vina => 0916123456, mobiphone => 0906123456, vnmobile => 0926123456, beeline => 0199123456\r\n    \"amount\": \"100000\",\r\n    \"signature\": \"{{mobile_topup_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{ebill_base_url}}/api/v1/service/topup/charging",
									"host": [
										"{{ebill_base_url}}"
									],
									"path": [
										"api",
										"v1",
										"service",
										"topup",
										"charging"
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Server",
									"value": "nginx/1.10.3"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.4.4"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "Date",
									"value": "Thu, 26 May 2022 04:23:49 GMT"
								},
								{
									"key": "X-RateLimit-Limit",
									"value": "500"
								},
								{
									"key": "X-RateLimit-Remaining",
									"value": "498"
								}
							],
							"cookie": [],
							"body": "{\n    \"errorCode\": 0,\n    \"message\": \"Thành công\",\n    \"transaction\": {\n        \"phoneNumber\": \"0866123456\",\n        \"amount\": 97000,\n        \"topupAmount\": 100000,\n        \"appotapayTransId\": \"01G3Z9PGM996HHKTW14WC5EJT9\",\n        \"time\": \"26-05-2022 11:23:49\"\n    },\n    \"account\": {\n        \"balance\": 23119101\n    },\n    \"signature\": \"94f19f99829d73b8fef31e0c657eb9d05302804922fc53ab614ea5aea414f421\"\n}"
						},
						{
							"name": "FAILED",
							"originalRequest": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"partnerRefId\": \"{{mobile_topup_request_id}}\",\r\n    \"telco\": \"viettel\",\r\n    \"telcoServiceType\": \"prepaid\",\r\n    \"phoneNumber\": \"0866123457\", // viettel => 0866123457, vina => 0916123457, mobiphone => 0906123457, vnmobile => 0926123457, beeline => 0199123457\r\n    \"amount\": \"100000\",\r\n    \"signature\": \"{{mobile_topup_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{ebill_base_url}}/api/v1/service/topup/charging",
									"host": [
										"{{ebill_base_url}}"
									],
									"path": [
										"api",
										"v1",
										"service",
										"topup",
										"charging"
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Server",
									"value": "nginx/1.10.3"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.4.4"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "Date",
									"value": "Thu, 26 May 2022 04:24:16 GMT"
								},
								{
									"key": "X-RateLimit-Limit",
									"value": "500"
								},
								{
									"key": "X-RateLimit-Remaining",
									"value": "499"
								}
							],
							"cookie": [],
							"body": "{\n    \"errorCode\": 33,\n    \"message\": \"Giao dịch không thành công\"\n}"
						},
						{
							"name": "PENDING",
							"originalRequest": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"partnerRefId\": \"{{mobile_topup_request_id}}\",\r\n    \"telco\": \"viettel\",\r\n    \"telcoServiceType\": \"prepaid\",\r\n    \"phoneNumber\": \"0866123458\", // viettel => 0866123458, vina => 0916123458, mobiphone => 0906123458, vnmobile => 0926123458, beeline => 0199123458\r\n    \"amount\": \"100000\",\r\n    \"signature\": \"{{mobile_topup_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{ebill_base_url}}/api/v1/service/topup/charging",
									"host": [
										"{{ebill_base_url}}"
									],
									"path": [
										"api",
										"v1",
										"service",
										"topup",
										"charging"
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Server",
									"value": "nginx/1.10.3"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.4.4"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "Date",
									"value": "Thu, 26 May 2022 04:24:46 GMT"
								},
								{
									"key": "X-RateLimit-Limit",
									"value": "500"
								},
								{
									"key": "X-RateLimit-Remaining",
									"value": "498"
								}
							],
							"cookie": [],
							"body": "{\n    \"errorCode\": 169,\n    \"message\": \"Giao dịch đang chờ xử lý\"\n}"
						}
					]
				},
				{
					"name": "Kiểm tra trạng thái giao dịch",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/topup/transaction/{{mobile_topup_request_id}}",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"topup",
								"transaction",
								"{{mobile_topup_request_id}}"
							]
						},
						"description": "API được sử dụng để kiểm tra trạng thái giao dịch"
					},
					"response": []
				},
				{
					"name": "API Truy vấn số dư tài khoản",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{ebill_base_url}}/api/v1/service/accounts/balance",
							"host": [
								"{{ebill_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"service",
								"accounts",
								"balance"
							]
						},
						"description": "API được sử dụng để kiểm tra trạng thái giao dịch"
					},
					"response": []
				}
			]
		},
		{
			"name": "Gạch thẻ AppotaCard",
			"item": [
				{
					"name": "Gạch thẻ",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"// functional\r",
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"function base64toHEX(base64) {\r",
									"    var raw = atob(base64);\r",
									"    var HEX = '';\r",
									"    for (i = 0; i < raw.length; i++) {\r",
									"        var _hex = raw.charCodeAt(i).toString(16)\r",
									"        HEX += (_hex.length == 2 ? _hex : '0' + _hex);\r",
									"    }\r",
									"    return HEX.toUpperCase();\r",
									"}\r",
									"\r",
									"function hexToBase64(str) {\r",
									"    return btoa(String.fromCharCode.apply(null,\r",
									"        str.replace(/\\r|\\n/g, \"\").replace(/([\\da-fA-F]{2}) ?/g, \"0x$1 \").replace(/ +$/, \"\").split(\" \"))\r",
									"    );\r",
									"}\r",
									"function encrypt (word,key) {\r",
									"    const encKey = CryptoJS.enc.Utf8.parse(key); // 16 length\r",
									"    const iv = CryptoJS.enc.Utf8.parse(generateRandomString(16));\r",
									"    let encrypted = '';\r",
									"    const srcs = CryptoJS.enc.Utf8.parse(word);\r",
									"    encrypted = CryptoJS.AES.encrypt(srcs, encKey, {\r",
									"        iv,\r",
									"        mode: CryptoJS.mode.CBC,\r",
									"        padding: CryptoJS.pad.Pkcs7\r",
									"    });\r",
									"    var encryptedHex = base64toHEX(encrypted.toString());\r",
									"    var base64result = hexToBase64(iv + encryptedHex);\r",
									"\r",
									"    return base64result;\r",
									"}\r",
									"\r",
									"\r",
									"// generate ID\r",
									"var cardChargingRequestId = generateRandomString(9);\r",
									"pm.collectionVariables.set('card_charging_request_id', cardChargingRequestId);\r",
									"// generate encrypt card code\r",
									"var cardCode = '123456789001';\r",
									"var cardSerial = 'OTA123456701';\r",
									"var partnerSecretKey = pm.collectionVariables.get('card_charging_secret_key') || '';\r",
									"//  card code => 123456789001 -> 123456789011\r",
									"//  card serial => OTA123456701 -> OTA123456711\r",
									"var encKey = partnerSecretKey.length > 16 ? (CryptoJS.SHA256(partnerSecretKey).toString()).substring(0, 16) : partnerSecretKey;\r",
									"var cardEncrypted = encrypt(cardCode, encKey);\r",
									"pm.collectionVariables.set('card_code_encrypted', cardEncrypted);\r",
									"pm.collectionVariables.set('card_charging_serial', cardSerial);\r",
									"\r",
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"let partnerCode = pm.collectionVariables.get('card_charging_partner_code');\r",
									"let signData = `${cardEncrypted}${cardSerial}${requestBody.vendor}${partnerCode}${requestBody.service_name}${cardChargingRequestId}${partnerSecretKey}`;\r",
									"console.log(signData);\r",
									"const cardChargingSignature = CryptoJS.SHA256(signData).toString()\r",
									"pm.collectionVariables.set('card_charging_request_signature', cardChargingSignature)\r",
									"\r",
									"// JWT generation script adapted from\r",
									"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d\\\r",
									"// Set headers for JWT\r",
									"var header = {\r",
									"\t'typ': 'JWT',\r",
									"\t'alg': 'HS256',\r",
									"    'cty': 'appotapay-api;v=1'\r",
									"};\r",
									"\r",
									"// Prepare timestamp in seconds\r",
									"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
									"\r",
									"var data = {\r",
									"\t'iss': pm.collectionVariables.get('card_charging_partner_code') || '',\r",
									"\t'api_key': pm.collectionVariables.get('card_charging_api_key') || '',\r",
									"    'jti': (pm.collectionVariables.get('card_charging_api_key') || '')+currentTimestamp,\r",
									"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation\r",
									"}\r",
									"\r",
									"\r",
									"function base64url(source) {\r",
									"    // Encode in classical base64\r",
									"    encodedSource = CryptoJS.enc.Base64.stringify(source)\r",
									"    \r",
									"    // Remove padding equal characters\r",
									"    encodedSource = encodedSource.replace(/=+$/, '')\r",
									"    \r",
									"    // Replace characters according to base64url specifications\r",
									"    encodedSource = encodedSource.replace(/\\+/g, '-')\r",
									"    encodedSource = encodedSource.replace(/\\//g, '_')\r",
									"    \r",
									"    return encodedSource\r",
									"}\r",
									"\r",
									"// encode header\r",
									"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))\r",
									"var encodedHeader = base64url(stringifiedHeader)\r",
									"\r",
									"// encode data\r",
									"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))\r",
									"var encodedData = base64url(stringifiedData)\r",
									"\r",
									"// build token\r",
									"var token = `${encodedHeader}.${encodedData}`\r",
									"\r",
									"// sign token\r",
									"var signature = CryptoJS.HmacSHA256(token, partnerSecretKey)\r",
									"signature = base64url(signature)\r",
									"var signedToken = `${token}.${signature}`\r",
									"\r",
									"pm.collectionVariables.set('card_charging_jwt_token', signedToken);\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().error_code).to.eql('00');\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('card_charging_partner_code') || '';\r",
									"// signData = amount + appotapayTransId + errorCode + phoneNumber + time + topupAmount\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "POST",
						"header": [
							{
								"key": "X-APPOTAPAY-AUTH",
								"value": "{{card_charging_jwt_token}}",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"code\": \"{{card_code_encrypted}}\",\r\n    \"serial\": \"{{card_charging_serial}}\",\r\n    \"vendor\": \"appota\",\r\n    \"partner_code\": \"{{card_charging_partner_code}}\", \r\n    \"service_name\": \"TEST\",\r\n    \"transaction_id\": \"{{card_charging_request_id}}\",\r\n    \"signature\": \"{{card_charging_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{card_charging_url}}/v1/sandbox/services/card_charging?api_key={{card_charging_api_key}}",
							"host": [
								"{{card_charging_url}}"
							],
							"path": [
								"v1",
								"sandbox",
								"services",
								"card_charging"
							],
							"query": [
								{
									"key": "api_key",
									"value": "{{card_charging_api_key}}"
								}
							]
						},
						"description": "API được sử dụng để nạp tiền điện thoại trực tiếp"
					},
					"response": [
						{
							"name": "Success",
							"originalRequest": {
								"method": "POST",
								"header": [
									{
										"key": "X-APPOTAPAY-AUTH",
										"value": "{{card_charging_jwt_token}}",
										"type": "text"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"code\": \"{{card_code_encrypted}}\",\r\n    \"serial\": \"{{card_charging_serial}}\",\r\n    \"vendor\": \"appota\",\r\n    \"partner_code\": \"{{card_charging_partner_code}}\", \r\n    \"service_name\": \"TEST\",\r\n    \"transaction_id\": \"{{card_charging_request_id}}\",\r\n    \"signature\": \"{{card_charging_request_signature}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{card_charging_url}}/v1/sandbox/services/card_charging?api_key={{card_charging_api_key}}",
									"host": [
										"{{card_charging_url}}"
									],
									"path": [
										"v1",
										"sandbox",
										"services",
										"card_charging"
									],
									"query": [
										{
											"key": "api_key",
											"value": "{{card_charging_api_key}}"
										}
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Date",
									"value": "Mon, 30 May 2022 02:56:19 GMT"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "Vary",
									"value": "Accept-Encoding"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.1.33"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "X-Frame-Options",
									"value": "NEVER"
								},
								{
									"key": "X-XSS-Protection",
									"value": "1; mode=block"
								},
								{
									"key": "Strict-Transport-Security",
									"value": "max-age=15724800; includeSubDomains"
								},
								{
									"key": "Content-Encoding",
									"value": "gzip"
								}
							],
							"cookie": [],
							"body": "{\n    \"error_code\": \"00\",\n    \"message\": \"Giao dịch thành công\",\n    \"data\": {\n        \"amount\": 10000,\n        \"serial\": \"OTA123456701\",\n        \"transaction_id\": \"01G49E95EGK2DM11ZT652Q6C8R\",\n        \"time\": \"30/05/2022 09:56:19 GMT+7\"\n    }\n}"
						}
					]
				},
				{
					"name": "Kiểm tra trạng thái giao dịch",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"//Generate Signature\r",
									"var requestBody = JSON.parse(request['data']);\r",
									"let partnerCode = pm.collectionVariables.get('card_charging_partner_code');\r",
									"let cardChargingRequestId = pm.collectionVariables.get('card_charging_request_id');\r",
									"var partnerSecretKey = pm.collectionVariables.get('card_charging_secret_key') || '';\r",
									"let signData = `${partnerCode}${cardChargingRequestId}${partnerSecretKey}`;\r",
									"console.log(signData);\r",
									"const cardChargingSignature = CryptoJS.SHA256(signData).toString()\r",
									"pm.collectionVariables.set('card_charging_request_signature', cardChargingSignature)\r",
									"\r",
									"// JWT generation script adapted from\r",
									"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d\\\r",
									"// Set headers for JWT\r",
									"var header = {\r",
									"\t'typ': 'JWT',\r",
									"\t'alg': 'HS256',\r",
									"    'cty': 'appotapay-api;v=1'\r",
									"};\r",
									"\r",
									"// Prepare timestamp in seconds\r",
									"var currentTimestamp = Math.floor(Date.now() / 1000)\r",
									"\r",
									"var data = {\r",
									"\t'iss': pm.collectionVariables.get('card_charging_partner_code') || '',\r",
									"\t'api_key': pm.collectionVariables.get('card_charging_api_key') || '',\r",
									"    'jti': (pm.collectionVariables.get('card_charging_api_key') || '')+currentTimestamp,\r",
									"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation\r",
									"}\r",
									"\r",
									"\r",
									"function base64url(source) {\r",
									"    // Encode in classical base64\r",
									"    encodedSource = CryptoJS.enc.Base64.stringify(source)\r",
									"    \r",
									"    // Remove padding equal characters\r",
									"    encodedSource = encodedSource.replace(/=+$/, '')\r",
									"    \r",
									"    // Replace characters according to base64url specifications\r",
									"    encodedSource = encodedSource.replace(/\\+/g, '-')\r",
									"    encodedSource = encodedSource.replace(/\\//g, '_')\r",
									"    \r",
									"    return encodedSource\r",
									"}\r",
									"\r",
									"// encode header\r",
									"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))\r",
									"var encodedHeader = base64url(stringifiedHeader)\r",
									"\r",
									"// encode data\r",
									"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))\r",
									"var encodedData = base64url(stringifiedData)\r",
									"\r",
									"// build token\r",
									"var token = `${encodedHeader}.${encodedData}`\r",
									"\r",
									"// sign token\r",
									"var signature = CryptoJS.HmacSHA256(token, partnerSecretKey)\r",
									"signature = base64url(signature)\r",
									"var signedToken = `${token}.${signature}`\r",
									"\r",
									"pm.collectionVariables.set('card_charging_jwt_token', signedToken);\r",
									""
								],
								"type": "text/javascript"
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().error_code).to.eql('00');\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"var partnerSecretKey = pm.collectionVariables.get('card_charging_partner_code') || '';\r",
									"// signData = amount + appotapayTransId + errorCode + phoneNumber + time + topupAmount\r",
									"\r",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"protocolProfileBehavior": {
						"disableBodyPruning": true
					},
					"request": {
						"auth": {
							"type": "noauth"
						},
						"method": "GET",
						"header": [
							{
								"key": "X-APPOTAPAY-AUTH",
								"value": "{{card_charging_jwt_token}}",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"partner_code\": \"{{card_charging_partner_code}}\", \r\n    \"transaction_id\": \"{{card_charging_request_id}}\",\r\n    \"signature\": \"{{card_charging_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{card_charging_url}}/v1/sandbox/services/transaction/check?api_key={{card_charging_api_key}}",
							"host": [
								"{{card_charging_url}}"
							],
							"path": [
								"v1",
								"sandbox",
								"services",
								"transaction",
								"check"
							],
							"query": [
								{
									"key": "api_key",
									"value": "{{card_charging_api_key}}"
								}
							]
						},
						"description": "API được sử dụng để nạp tiền điện thoại trực tiếp"
					},
					"response": [
						{
							"name": "Success",
							"originalRequest": {
								"method": "GET",
								"header": [
									{
										"key": "X-APPOTAPAY-AUTH",
										"value": "{{card_charging_jwt_token}}",
										"type": "text"
									}
								],
								"url": {
									"raw": "{{card_charging_url}}/v1/sandbox/services/transaction/check?api_key={{card_charging_api_key}}",
									"host": [
										"{{card_charging_url}}"
									],
									"path": [
										"v1",
										"sandbox",
										"services",
										"transaction",
										"check"
									],
									"query": [
										{
											"key": "api_key",
											"value": "{{card_charging_api_key}}"
										}
									]
								}
							},
							"status": "OK",
							"code": 200,
							"_postman_previewlanguage": "json",
							"header": [
								{
									"key": "Date",
									"value": "Mon, 30 May 2022 04:22:01 GMT"
								},
								{
									"key": "Content-Type",
									"value": "application/json"
								},
								{
									"key": "Transfer-Encoding",
									"value": "chunked"
								},
								{
									"key": "Connection",
									"value": "keep-alive"
								},
								{
									"key": "Vary",
									"value": "Accept-Encoding"
								},
								{
									"key": "X-Powered-By",
									"value": "PHP/7.1.33"
								},
								{
									"key": "Cache-Control",
									"value": "no-cache, private"
								},
								{
									"key": "X-Frame-Options",
									"value": "NEVER"
								},
								{
									"key": "X-XSS-Protection",
									"value": "1; mode=block"
								},
								{
									"key": "Strict-Transport-Security",
									"value": "max-age=15724800; includeSubDomains"
								},
								{
									"key": "Content-Encoding",
									"value": "gzip"
								}
							],
							"cookie": [],
							"body": "{\n    \"error_code\": \"00\",\n    \"message\": \"Giao dịch thành công\",\n    \"data\": {\n        \"amount\": 10000,\n        \"serial\": \"OTA123456701\",\n        \"transaction_id\": \"01G49EBPTHW9MDPKT0J1QBX399\",\n        \"time\": \"09:57:42 30/05/2022 GMT+7\"\n    }\n}"
						}
					]
				}
			]
		},
		{
			"name": "Thanh toán định kỳ",
			"item": [
				{
					"name": "Tạo customer",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var customerRefId = generateRandomString(9);\r",
									"pm.collectionVariables.set('customer_ref_id', customerRefId);"
								],
								"type": "text/javascript",
								"packages": {}
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"pm.collectionVariables.set('customer_ref_id', jsonData.customerRefId);\r",
									"pm.collectionVariables.set('customer_id', jsonData.customerId)"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Authorization",
								"value": "Bearer wnNjBOTe56miXvm1rPeCQcVEYUuo3CZbIIsQGHl21a4D7pthg9JSuMHAwDM0O2Fd",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							},
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							},
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"customerRefId\": \"{{customer_ref_id}}\",\r\n    \"customer\": {\r\n        \"firstName\": \"Duong\",\r\n        \"lastName\": \"Phan \",\r\n        \"mobileNumber\": \"+84123456789\",\r\n        \"email\": \"test@appotapay.com\",\r\n        \"gender\": \"MALE\",\r\n        \"dateOfBirth\": \"1996-04-23\",\r\n        \"placeOfBirth\": \"HN\",\r\n        \"nationality\": \"EC\"\r\n    }\r\n}\r\n",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/customers",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"customers"
							]
						}
					},
					"response": []
				},
				{
					"name": "Lấy chi tiết customer",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							}
						],
						"url": {
							"raw": "{{payment_base_url}}/api/v1/customers/{{customer_ref_id}}",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"customers",
								"{{customer_ref_id}}"
							]
						}
					},
					"response": []
				},
				{
					"name": "Cập nhật customer",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "Language",
								"value": "en",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"customer\": {\r\n        \"firstName\": \"Duong\",\r\n        \"lastName\": \"Phan \",\r\n        \"mobileNumber\": \"+84123456789\",\r\n        \"email\": \"test@appotapay.com\",\r\n        \"gender\": \"MALE\",\r\n        \"dateOfBirth\": \"1996-04-23\",\r\n        \"placeOfBirth\": \"HN\",\r\n        \"nationality\": \"EC\"\r\n    }\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/customers/{{customer_id}}",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"customers",
								"{{customer_id}}"
							]
						}
					},
					"response": []
				},
				{
					"name": "Create payment method",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var paymentMethodRefId = generateRandomString(9);\r",
									"pm.collectionVariables.set('payment_method_ref_id', paymentMethodRefId);"
								],
								"type": "text/javascript",
								"packages": {}
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"pm.collectionVariables.set('payment_method_ref_id', jsonData.paymentMethodRefId);\r",
									"pm.collectionVariables.set('payment_method_id', jsonData.paymentMethodId)"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Authorization",
								"value": "Bearer wnNjBOTe56miXvm1rPeCQcVEYUuo3CZbIIsQGHl21a4D7pthg9JSuMHAwDM0O2Fd",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							},
							{
								"key": "X-ACCOUNT-REF-ID",
								"value": "ab1c1c28-49d2-43b1-913a-4758f1c4f809",
								"type": "text",
								"disabled": true
							},
							{
								"key": "X-ACCOUNT-REF-ID",
								"value": "a85a6131-35a0-4e54-b213-d74e23349974",
								"type": "text",
								"disabled": true
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"paymentMethodRefId\": \"{{payment_method_ref_id}}\",\r\n    \"customerId\": \"{{customer_id}}\",\r\n    \"country\": \"VN\",\r\n    \"currency\": \"VND\",\r\n    \"paymentMethod\": \"CC_SUBS\",\r\n    \"reusability\": \"MULTIPLE_USE\",\r\n    \"card\": {\r\n        \"properties\" : {\r\n           \"skipThreeDSecure\": \"YES\",\r\n           \"successReturnUrl\": \"http://yourwebsite.com/success\",\r\n           \"failureReturnUrl\": \"http://yourwebsite.com/failure\"\r\n        },\r\n        \"cardInfo\" : {\r\n           \"cardNumber\": \"4000000000001091\",\r\n           \"cardMonth\": \"02\",\r\n           \"cardYear\": \"2025\",\r\n           \"cardHolderName\": \"MAI MINH\"\r\n        }\r\n    },\r\n    \"billing\": {\r\n        \"country\": \"VN\",\r\n        \"city\": \"Ha Noi\",\r\n        \"provinceState\": \"CG\",\r\n        \"address\": \"CG\",\r\n        \"zipcode\": \"530000\"\r\n    }\r\n}\r\n",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/payment-methods",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"payment-methods"
							]
						}
					},
					"response": []
				},
				{
					"name": "Lấy chi tiết payment method",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"pm.collectionVariables.set('payment_method_ref_id', jsonData.paymentMethodRefId);\r",
									"pm.collectionVariables.set('payment_method_id', jsonData.paymentMethodId)"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"protocolProfileBehavior": {
						"disableBodyPruning": true
					},
					"request": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"orderId\": \"WEWE1636186777\",\r\n    \"signature\": \"{{payment_request_signature}}\"\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/payment-methods/{{payment_method_ref_id}}",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"payment-methods",
								"{{payment_method_ref_id}}"
							]
						}
					},
					"response": []
				},
				{
					"name": "Lấy danh sách payment method",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "X-APPOTAPAY-AUTH",
								"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6ImFwcG90YXBheS1hcGk7dj0xIn0.eyJpc3MiOiJIVU5HSEQiLCJhcGlfa2V5IjoiUDAwcklVZW1MUXFrUXVIZk5WVERqZUlYQXJzWlBDMUQiLCJqdGkiOiJQMDBySVVlbUxRcWtRdUhmTlZURGplSVhBcnNaUEMxRDE3MTI4MjExNTIiLCJleHAiOjE3MTI4MjQxNTJ9.urZBUNZHt2ZfFyjDFR-jHQEZx_ieasy4B8UdF9upB78"
							},
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/payment-methods",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"payment-methods"
							],
							"query": [
								{
									"key": "page",
									"value": "1",
									"disabled": true
								},
								{
									"key": "paymentMethod",
									"value": "CC_SUBS",
									"disabled": true
								},
								{
									"key": "reusability",
									"value": "MULTIPLE_USE",
									"disabled": true
								}
							]
						}
					},
					"response": []
				},
				{
					"name": "Tạo plan",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {\r",
									"    var text = '';\r",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r",
									"    for (var i = 0; i < length; i++) {\r",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));\r",
									"    }\r",
									"    return text;\r",
									"}\r",
									"var planRefId = generateRandomString(9);\r",
									"pm.collectionVariables.set('plan_ref_id', planRefId);"
								],
								"type": "text/javascript",
								"packages": {}
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"pm.collectionVariables.set('plan_ref_id', jsonData.planRefId);\r",
									"pm.collectionVariables.set('plan_id', jsonData.planId)"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Authorization",
								"value": "Bearer wnNjBOTe56miXvm1rPeCQcVEYUuo3CZbIIsQGHl21a4D7pthg9JSuMHAwDM0O2Fd",
								"type": "text"
							},
							{
								"key": "Content-Type",
								"value": "application/json",
								"type": "text"
							},
							{
								"key": "X-ACCOUNT-REF-ID",
								"value": "ab1c1c28-49d2-43b1-913a-4758f1c4f809",
								"type": "text",
								"disabled": true
							},
							{
								"key": "X-ACCOUNT-REF-ID",
								"value": "a85a6131-35a0-4e54-b213-d74e23349974",
								"type": "text",
								"disabled": true
							},
							{
								"key": "x-language",
								"value": "en",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"planRefId\": \"{{plan_ref_id}}\",\r\n    \"customerId\": \"{{customer_id}}\",\r\n    \"currency\": \"VND\",\r\n    \"amount\": 10000,\r\n    \"paymentMethods\": [\r\n        {\r\n            \"paymentMethodId\": \"{{payment_method_id}}\",\r\n            \"rank\": 1\r\n        }\r\n    ],\r\n    \"paymentLinkForFailedAttempt\": \"YES\",\r\n    \"immediateActionType\": \"FULL_AMOUNT\",\r\n    \"failedCycleAction\": \"STOP\",\r\n    \"schedule\": {\r\n        \"interval\": \"DAY\",\r\n        \"intervalCount\": 3,\r\n        \"totalRecurrence\": 2,\r\n        \"anchorDate\": \"2024-06-28T15:23:40+07:00\",\r\n        \"retryInterval\": \"DAY\",\r\n        \"retryIntervalCount\": 1,\r\n        \"totalRetry\": 3\r\n    },\r\n    \"currencyExchange\": {\r\n        \"amount\": 4200,\r\n        \"currency\": \"USD\"\r\n    }\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans"
							]
						}
					},
					"response": []
				},
				{
					"name": "Lấy chi tiết plan",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						},
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Status code is 200\", function () {\r",
									"    pm.response.to.have.status(200);\r",
									"});\r",
									"pm.test(\"Error code is success\", function () {\r",
									"    pm.expect(pm.response.json().errorCode).to.eql(0);\r",
									"});\r",
									"\r",
									"var jsonData = JSON.parse(responseBody);\r",
									"pm.collectionVariables.set('plan_ref_id', jsonData.planRefId);\r",
									"pm.collectionVariables.set('plan_id', jsonData.planId)"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Language",
								"value": "en",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_ref_id}}",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_ref_id}}"
							]
						}
					},
					"response": []
				},
				{
					"name": "Lấy danh sách cycle của plan",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}/cycles",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}",
								"cycles"
							]
						}
					},
					"response": []
				},
				{
					"name": "Cập nhật plan",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							},
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"amount\": 10000,\r\n    \"currencyExchange\": {\r\n        \"amount\": 4200,\r\n        \"currency\": \"USD\"\r\n    }\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}"
							]
						}
					},
					"response": []
				},
				{
					"name": "Deactive plan",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							},
							{
								"key": "",
								"value": "",
								"type": "text",
								"disabled": true
							}
						],
						"body": {
							"mode": "raw",
							"raw": "",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}/deactivate",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}",
								"deactivate"
							]
						}
					},
					"response": []
				},
				{
					"name": "Lấy chi tiết cycle",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Language",
								"value": "en",
								"type": "text"
							}
						],
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}/cycles/01J7AVRE2GYX6E885YFQ9DTKZR",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}",
								"cycles",
								"01J7AVRE2GYX6E885YFQ9DTKZR"
							]
						}
					},
					"response": []
				},
				{
					"name": "Cập nhật cycle",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "Language",
								"value": "en",
								"type": "text"
							},
							{
								"key": "X-ACCOUNT-REF-ID",
								"value": "",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"currency\": \"VND\",\r\n    \"amount\": 10000\r\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}/cycles/01J7AVRE2GYX6E885YFQ9DTKZR",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}",
								"cycles",
								"01J7AVRE2GYX6E885YFQ9DTKZR"
							]
						}
					},
					"response": []
				},
				{
					"name": "Cancel cycle",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}/cycles/01J7AVRE2GYX6E885YFQ9DTKZR/cancel",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}",
								"cycles",
								"01J7AVRE2GYX6E885YFQ9DTKZR",
								"cancel"
							]
						}
					},
					"response": []
				},
				{
					"name": "Force cycle attempt",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": "",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_base_url}}/api/v1/subs/plans/{{plan_id}}/cycles/01J7AVRE2GYX6E885YFQ9DTKZR/force-attempt",
							"host": [
								"{{payment_base_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"plans",
								"{{plan_id}}",
								"cycles",
								"01J7AVRE2GYX6E885YFQ9DTKZR",
								"force-attempt"
							]
						}
					},
					"response": []
				},
				{
					"name": "Hoàn tiền",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									"function generateRandomString(length) {",
									"    var text = '';",
									"    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';",
									"    for (var i = 0; i < length; i++) {",
									"        text += possible.charAt(Math.floor(Math.random() * possible.length));",
									"    }",
									"    return text;",
									"}",
									"var refundRefId = generateRandomString(9);",
									"pm.collectionVariables.set('refund_ref_id', refundRefId);"
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Language",
								"value": "en",
								"type": "text",
								"disabled": true
							},
							{
								"key": "X-ACCOUNT-REF-ID",
								"value": "ab1c1c28-49d2-43b1-913a-4758f1c4f809",
								"type": "text",
								"disabled": true
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"refundRefId\": \"{{refund_ref_id}}\",\n    \"attemptId\": \"01J7ATC3M4KQC2ATZC8PC4EZA1\",\n    \"reason\": \"FRAUDULENT\",\n    \"currency\": \"VND\",\n    \"amount\": 10000\n}",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_endpoint_url}}/api/v1/subs/refunds",
							"host": [
								"{{payment_endpoint_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"refunds"
							]
						}
					},
					"response": []
				},
				{
					"name": "Chi tiết  refund cycle",
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"exec": [
									""
								],
								"type": "text/javascript",
								"packages": {}
							}
						}
					],
					"protocolProfileBehavior": {
						"disableBodyPruning": true
					},
					"request": {
						"method": "GET",
						"header": [
							{
								"key": "Language",
								"value": "en",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "",
							"options": {
								"raw": {
									"language": "json"
								}
							}
						},
						"url": {
							"raw": "{{payment_endpoint_url}}/api/v1/subs/refunds/{{refund_ref_id}}",
							"host": [
								"{{payment_endpoint_url}}"
							],
							"path": [
								"api",
								"v1",
								"subs",
								"refunds",
								"{{refund_ref_id}}"
							]
						}
					},
					"response": []
				}
			]
		}
	],
	"auth": {
		"type": "apikey",
		"apikey": [
			{
				"key": "value",
				"value": "{{jwt_token}}",
				"type": "string"
			},
			{
				"key": "key",
				"value": "X-APPOTAPAY-AUTH",
				"type": "string"
			}
		]
	},
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"exec": [
					"// JWT generation script adapted from",
					"// https://gist.github.com/corbanb/db03150abbe899285d6a86cc480f674d",
					"var partnerSecretKey = pm.collectionVariables.get('secret_key') || ''",
					"",
					"// Set headers for JWT",
					"var header = {",
					"\t'typ': 'JWT',",
					"\t'alg': 'HS256',",
					"    'cty': 'appotapay-api;v=1'",
					"};",
					"",
					"// Prepare timestamp in seconds",
					"var currentTimestamp = Math.floor(Date.now() / 1000)",
					"",
					"var data = {",
					"\t'iss': pm.collectionVariables.get('partner_code') || '',",
					"\t'api_key': pm.collectionVariables.get('api_key') || '',",
					"    'jti': (pm.collectionVariables.get('api_key') || '')+currentTimestamp,",
					"\t'exp': currentTimestamp + 3000, // expiry time is 30 seconds from time of creation",
					"}",
					"",
					"",
					"function base64url(source) {",
					"    // Encode in classical base64",
					"    encodedSource = CryptoJS.enc.Base64.stringify(source)",
					"    ",
					"    // Remove padding equal characters",
					"    encodedSource = encodedSource.replace(/=+$/, '')",
					"    ",
					"    // Replace characters according to base64url specifications",
					"    encodedSource = encodedSource.replace(/\\+/g, '-')",
					"    encodedSource = encodedSource.replace(/\\//g, '_')",
					"    ",
					"    return encodedSource",
					"}",
					"",
					"// encode header",
					"var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header))",
					"var encodedHeader = base64url(stringifiedHeader)",
					"",
					"// encode data",
					"var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data))",
					"var encodedData = base64url(stringifiedData)",
					"",
					"// build token",
					"var token = `${encodedHeader}.${encodedData}`",
					"",
					"// sign token",
					"var signature = CryptoJS.HmacSHA256(token, partnerSecretKey)",
					"signature = base64url(signature)",
					"var signedToken = `${token}.${signature}`",
					"",
					"pm.collectionVariables.set('jwt_token', signedToken);"
				]
			}
		},
		{
			"listen": "test",
			"script": {
				"type": "text/javascript",
				"exec": [
					""
				]
			}
		}
	],
	"variable": [
		{
			"key": "ebill_base_url",
			"value": "https://gateway.dev.appotapay.com"
		},
		{
			"key": "payment_endpoint_url",
			"value": "https://payment.dev.appotapay.com"
		},
		{
			"key": "payment_base_url",
			"value": "https://gateway.dev.appotapay.com",
			"type": "string"
		},
		{
			"key": "partner_code",
			"value": "APPOTAPAY"
		},
		{
			"key": "api_key",
			"value": "FJcmF8uj2ISveL5FvvNk4pnp8xrhINz8"
		},
		{
			"key": "secret_key",
			"value": "XAonJgy14YhtePEITXhyBS2unjfJLAV3"
		},
		{
			"key": "card_charging_partner_code",
			"value": "APPOTAPAY"
		},
		{
			"key": "card_charging_api_key",
			"value": "AK-P001-1BSJB0-C4BAC3F27CF41E71"
		},
		{
			"key": "card_charging_secret_key",
			"value": "eKUJp2IzeKUJp2Izwl11ub9Rkub9Rkwl"
		},
		{
			"key": "jwt_token",
			"value": ""
		},
		{
			"key": "bill_code",
			"value": ""
		},
		{
			"key": "bill_expiry_time",
			"value": ""
		},
		{
			"key": "request_signature",
			"value": ""
		},
		{
			"key": "start_of_day",
			"value": ""
		},
		{
			"key": "end_of_day",
			"value": ""
		},
		{
			"key": "transfer_payment_id",
			"value": ""
		},
		{
			"key": "transfer_request_signature",
			"value": ""
		},
		{
			"key": "get_account_info_request_id",
			"value": ""
		},
		{
			"key": "get_account_info_request_signature",
			"value": ""
		},
		{
			"key": "bill_request_id",
			"value": ""
		},
		{
			"key": "bill_request_signature",
			"value": ""
		},
		{
			"key": "e_bill_payment_request_id",
			"value": ""
		},
		{
			"key": "e_bill_payment_request_signature",
			"value": ""
		},
		{
			"key": "e_bill_detail",
			"value": ""
		},
		{
			"key": "e_bill_amount",
			"value": ""
		},
		{
			"key": "shop_card_request_id",
			"value": ""
		},
		{
			"key": "shop_card_request_signature",
			"value": ""
		},
		{
			"key": "mobile_topup_request_id",
			"value": ""
		},
		{
			"key": "mobile_topup_request_signature",
			"value": ""
		},
		{
			"key": "card_charging_url",
			"value": ""
		},
		{
			"key": "card_charging_request_id",
			"value": ""
		},
		{
			"key": "card_code_encrypted",
			"value": ""
		},
		{
			"key": "card_charging_serial",
			"value": ""
		},
		{
			"key": "card_charging_request_signature",
			"value": ""
		},
		{
			"key": "card_charging_jwt_token",
			"value": ""
		},
		{
			"key": "payment_order_id",
			"value": ""
		},
		{
			"key": "payment_link_order_id",
			"value": ""
		},
		{
			"key": "white_label_order_id",
			"value": ""
		},
		{
			"key": "refund_id",
			"value": ""
		},
		{
			"key": "appotapay_trans_id",
			"value": ""
		},
		{
			"key": "refund_ref_id",
			"value": ""
		},
		{
			"key": "customer_ref_id",
			"value": ""
		},
		{
			"key": "customer_id",
			"value": ""
		},
		{
			"key": "payment_method_ref_id",
			"value": ""
		},
		{
			"key": "payment_method_id",
			"value": ""
		},
		{
			"key": "plan_ref_id",
			"value": ""
		},
		{
			"key": "plan_id",
			"value": ""
		}
	]
}