# 1. Password-Free Authorization Login
# Request URL
/api/jt/wallet/open/user/getLoginToken
# Request Method
- POST
# Request Headers
| Parameter Name | Required | Type | Description |
|---|---|---|---|
| Content-Type | Yes | string | application/json |
# Request Body Parameters
| Parameter Name | Required | Type | Description | Example (Before Encryption) | Example (After Encryption) |
|---|---|---|---|---|---|
| appId | Yes | string | Application APPID | ||
| aesKey | Yes | string | AES Key (RSA encrypted) | "{\"key\": \"qwertasdfgzxcvbn\", \"iv\": \"bvcxzgfdsatrewqy\"}" | YDPeqH0+MJiW5Jfi9CQXy/Btz4YkiZCOp5njAy5G5s87HaS/zgmQZBnDeNjFrSduAL1tC329XIJGX+u6SKZtRvtrCx5UhZGRviBBhA575mt99TcUqAVEjXRn+ShpZmg6U8N0IHl8TX8psyWiAzxIBkrDCqIlXODfNdr8/LgZcuQFgwQGurZ8QX9L9BZxBdOH1ksLqP0Dlr5awQYD9LAstA8nzZ9C9qXt7OD+XvE6qK/8pi9YYr02oqdaXyo2ypITz6HkXKibYSv6HDtPIy6h44Qgnc6psmE4bBmH7k6q27u0mqe3zFzXiZlF7NOIkl8inFKaR59jD06L/xbuM+oTOrKHThY7+FaObf1gVSRqrzucuv9gNgI2tZRkG5AzYCMTIER0zXfx2QtVUxmOvkl6+OAVBNnLC+N9KdzXSiUU1zehg3+VrosJqyNTfYT/8iY4NVa2IPzX5CN89lA3zYoDeiyBpzH71H86oU3xzoNQS00QrgWi0tK4WXaU+duPO+wLzfGv9/2G0I5Hgf2XkjFD+Ab8wWiDxJ0YfT1mBHtjkNtlvtrD4Sc48UClxE4vGMp4ekapd6+2yEzMYEVY4o/HUgE6QgeiGcE25yT8RC8yMxw4eHQnE4NTjwowdqm+Vq28iOw2IufRxjfcPyz7f9TgGGwhu/IHwh24exfJx73RKFA= |
| param | Yes | string | Parameter body (AES encrypted string) | "{\"timestamp\":1715595802,\"userId\":\"1095595801938341100\",\"mobile\":\"639123456778\"}" | u+wP+tVHRCDT21oIC32X+RogU3x5blBdikNSvRFuM9TkWMtc9WrZKCX6YIS1uezJZXR925qEBR6oVyCQ9tO6t7d0Z3xm/wKlufx2hQEfRbE= |
| sign | Yes | string | Signature (using pre-encryption param) | EJeMHGDlLu3DdbIK/52aID1soLrD0rfGcEEsAQ8cXFWaXQHioVwfZUD82U5g67NTXP/F/0Mhg6bK7n6rJlC/clYzqZ1kHmO2FbCdujw0ATY+FfM6VkgVT4pXr1jYmg3Xe23RDqhFvkDcOfRvaGPtnf64yrQG32MZps23TsbnafitDbtfqSoDIZkDCw1j1EH3Shhd64xKh9L3O8ivyF2UDOiHSAD8+18JXOxMWMFcR01STKE5B+zlEu5OA98+ClDBdroekBVKDeBeagwwQr+0zDFUvAb+2QIPKA2o0JM3ooituiaKVCgCVfndNjk8wIzKz2QYp+RhjVOC/u+8+Yoqb4KoWjGkMXgDbM1GZpdHG/BmzqXqhnNF0Y0LYS4bkITstlOm30nnHSljT5bxjk2Sq1hp9259SqMdp52OyoznxbRwEva5Wk5YPo+zD8IHOctEjkwWXz9/jo2evK6QcWCOH2LM6cG7EoP6Cg+5P2AUTofSMZsn/ZnAy6h9MXIuirDBiujrKMk85EY74s8i7yCNmjQ5NRbPbKsNTJbkxp2cRSMPzYPzOXXqEgKMmYzVQ5SSAcqFZIj2fAOL/3fG+2aEMn/8AFjJuD3/160BmYCZbAY4A2LJow6SGP/OcifvWPwoziJv0IP5Jff59w0mv6h0+3HnJg5YAcqK7dani1C0cAQ= |
# param Parameters (After Decryption)
| Parameter Name | Required | Type | Length | Example | Description |
|---|---|---|---|---|---|
| timestamp | Yes | long | - | 1677495496979 | Millisecond timestamp |
| userId | Yes | string | 1-32 | - | J&T user UUID unique identifier |
| mobile | Yes | string | - | - | Starts with 639, length 12 |
| terminalType | No | string | 20 | PC | Device type, enum: PC, default: PC |
| isIframe | No | string | 20 | N | Whether to open webpage in iframe, enum: Y, N, effective when device type is PC. Set to Y if needed, otherwise N. |
# Request Example
# Request Body
{
"appId": "733b887a4a784708bb369524db5b6ded",
"aesKey": "YDPeqH0+MJiW5Jfi9CQXy/Btz4YkiZCOp5njAy5G5s87HaS/zgmQZBnDeNjFrSduAL1tC329XIJGX+u6SKZtRvtrCx5UhZGRviBBhA575mt99TcUqAVEjXRn+ShpZmg6U8N0IHl8TX8psyWiAzxIBkrDCqIlXODfNdr8/LgZcuQFgwQGurZ8QX9L9BZxBdOH1ksLqP0Dlr5awQYD9LAstA8nzZ9C9qXt7OD+XvE6qK/8pi9YYr02oqdaXyo2ypITz6HkXKibYSv6HDtPIy6h44Qgnc6psmE4bBmH7k6q27u0mqe3zFzXiZlF7NOIkl8inFKaR59jD06L/xbuM+oTOrKHThY7+FaObf1gVSRqrzucuv9gNgI2tZRkG5AzYCMTIER0zXfx2QtVUxmOvkl6+OAVBNnLC+N9KdzXSiUU1zehg3+VrosJqyNTfYT/8iY4NVa2IPzX5CN89lA3zYoDeiyBpzH71H86oU3xzoNQS00QrgWi0tK4WXaU+duPO+wLzfGv9/2G0I5Hgf2XkjFD+Ab8wWiDxJ0YfT1mBHtjkNtlvtrD4Sc48UClxE4vGMp4ekapd6+2yEzMYEVY4o/HUgE6QgeiGcE25yT8RC8yMxw4eHQnE4NTjwowdqm+Vq28iOw2IufRxjfcPyz7f9TgGGwhu/IHwh24exfJx73RKFA=",
"sign": "EJeMHGDlLu3DdbIK/52aID1soLrD0rfGcEEsAQ8cXFWaXQHioVwfZUD82U5g67NTXP/F/0Mhg6bK7n6rJlC/clYzqZ1kHmO2FbCdujw0ATY+FfM6VkgVT4pXr1jYmg3Xe23RDqhFvkDcOfRvaGPtnf64yrQG32MZps23TsbnafitDbtfqSoDIZkDCw1j1EH3Shhd64xKh9L3O8ivyF2UDOiHSAD8+18JXOxMWMFcR01STKE5B+zlEu5OA98+ClDBdroekBVKDeBeagwwQr+0zDFUvAb+2QIPKA2o0JM3ooituiaKVCgCVfndNjk8wIzKz2QYp+RhjVOC/u+8+Yoqb4KoWjGkMXgDbM1GZpdHG/BmzqXqhnNF0Y0LYS4bkITstlOm30nnHSljT5bxjk2Sq1hp9259SqMdp52OyoznxbRwEva5Wk5YPo+zD8IHOctEjkwWXz9/jo2evK6QcWCOH2LM6cG7EoP6Cg+5P2AUTofSMZsn/ZnAy6h9MXIuirDBiujrKMk85EY74s8i7yCNmjQ5NRbPbKsNTJbkxp2cRSMPzYPzOXXqEgKMmYzVQ5SSAcqFZIj2fAOL/3fG+2aEMn/8AFjJuD3/160BmYCZbAY4A2LJow6SGP/OcifvWPwoziJv0IP5Jff59w0mv6h0+3HnJg5YAcqK7dani1C0cAQ=",
"param": "u+wP+tVHRCDT21oIC32X+RogU3x5blBdikNSvRFuM9TkWMtc9WrZKCX6YIS1uezJZXR925qEBR6oVyCQ9tO6t7d0Z3xm/wKlufx2hQEfRbE="
}
// After decryption
"aesKey": "{\"key\": \"qwertasdfgzxcvbn\", \"iv\": \"bvcxzgfdsatrewqy\"}"
"param": "{\"timestamp\":1715595802,\"userId\":\"1095595801938341100\",\"mobile\":\"639123456778\"}"
# RSA Sign And AES Encrypt Util
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class SignAndEncryptUtil {
/**
*
* @param param Param JsonString
*/
public static boolean verifySign(String param, String sign, String publicKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))));
signature.update(param.getBytes());
return signature.verify(Base64.getDecoder().decode(sign));
}
/**
*
* @param param Param JsonString
* @return sign
*/
public static String generateSign(String param, String privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))));
signature.update(param.getBytes());
byte[] bytes = signature.sign();
return Base64.getEncoder().encodeToString(bytes);
}
public static String encryptWithPrivateKey(String data, String privateKeyStr) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey =keyFactory.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encryptedBytes = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decryptWithPublicKey(String encryptedData, String publicKeyStr) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
return new String(cipher.doFinal(decodedBytes));
}
public static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCV+0mJmN5wOrfcPuAF6JKHQg066WX4/QYOAbhFe/yPJ+tu5QfKau9yptJcwenwV8Mj5DM1QWBAY/d0ThYpRkuPjL9zjWuOzrWFfMuB7EktY13a9F32QlnGJ4JIW5PAoRXl/fsbeZQbrKxnAHvZqOl/LFpNA/eSz4TZ2EegIfILFjTgOnL+g1ZgRiSRBk4DVhDtdDhwvwb0BBK1TAMV0btBJIykcNR7YYAG2+rMwpgtSlDkKB9KuSdtG72GeyAwRqMJJrl77+m1XfR9Py2r8cQ/O3Og7wzE/V1gFhwvZADludFZhgP8pskr9j1gJmU58S1+Xz9Bv5cdLFinzyNNadpTAgMBAAECggEAA3JM1E6g/e87fmIrf7dCdr071Ji8cSZPV08Ozvn0ac2/CUNWFH60levjdaI3IADESTTbQGQKNDCX5SJOPBCTd+8CD0O2rwdtAG5HtuqZG+PmqjtnVVtc+MK7qbIBCTIqcKiPdqgqkSA8rflC31OUWgnI4XAv5j3Cjcb8jl95UmvdNXYQlLeaDnFG24pf1pgbExJndM0fjz9bxFNHVYGa6RxCwbrNLdsKgB2sNg5dKxmZw7JvZtmCcDnb1LTC2sftJJVds4NlmMbWfTS8NVIQa3mKSuwD0jV79xQa+Ec7V6xsod73jz3nbAcKhTPN5B6DJKYtO+aqQKIUlmbSYHAiAQKBgQDHGIX7gIAqIP2gtOpmsvi1mRJeh9F4psaLGU3DMFSAl/Ht/Zs/SYP70mHFYtYvUEjLgpw+V9W48f7mRuAZoRJCKMlKkXlCfCqTImioXUXiPsOBeuglewwmVzw/hOVVh5v+xwIbDu6P8IexXtmAVroBwO3Jdxutsat79iGAr9H80wKBgQDA2SrFNpY/9UhLSQfzY2mm8Yng2Cu1rPTxZRRn4T/2i2vCArPFW/wNspPttEengnE5r7TUJr/a+jZUQz6gpSuNU4eKpOwYZ7QD2szC1UEs39Z/f7pIe7JKUUDdnubECCSR7Vs1uiKFvOILdCf9t/hmsq3+yaM0rGG3jhTa1kg8gQKBgQCZRykHanPBe2qoCgCYFlthu7onqtq6z3L1bgKvLgswgUpRljiqbZe+DMcW5rPM8ztH6oMNgCPbYfuDH7eyI45h/vKRhRPc+qjwY8I9NKnzt6xeh9gn2uaMsgaBRHgm8+NGL8JQQJurl1twU3yR0LMdXIH0480cWTeTlPdQEoxQ3wKBgQCs7U+j/lnmyjzkfX1qq3de4vJfM5imVYxjNd+BcwOXQdgD5cZsMBqp8bsiiOlD9P0w3DULlB+v7XRwRMhQ5ytRlFhTY6XuEHfkiPvZrb6+zY0bUV6qhnkOmSPQVx/ZIvAgBrYmTF2OjRwpZyRBKAnPlWPet9Lodbc+EGL1BPdLgQKBgBSUxIChyE3oo4rAMzCenOtywvyrOhjc5v4UrlvyhWuqej3T9rQ7NMDG0ba+F/guqj3ZruePNsU24X6nd1uiJvHW8XdvtZuGIfDDMOzFgn0G3m9hSXQNTCwaaaQaeuE7G5z1S+x07s6jyv2LfOBHwRuhOshg0bz96jpOIUkKipYH";
public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlftJiZjecDq33D7gBeiSh0INOull+P0GDgG4RXv8jyfrbuUHymrvcqbSXMHp8FfDI+QzNUFgQGP3dE4WKUZLj4y/c41rjs61hXzLgexJLWNd2vRd9kJZxieCSFuTwKEV5f37G3mUG6ysZwB72ajpfyxaTQP3ks+E2dhHoCHyCxY04Dpy/oNWYEYkkQZOA1YQ7XQ4cL8G9AQStUwDFdG7QSSMpHDUe2GABtvqzMKYLUpQ5CgfSrknbRu9hnsgMEajCSa5e+/ptV30fT8tq/HEPztzoO8MxP1dYBYcL2QA5bnRWYYD/KbJK/Y9YCZlOfEtfl8/Qb+XHSxYp88jTWnaUwIDAQAB";
/**
* main method: Demonstrates signature verification and encryption/decryption
*/
public static void main(String[] args) {
try {
// Test data
String param = "{\"timestamp\":1715595802,\"userId\":\"1095595801938341100\",\"mobile\":\"639123456778\"}";
String aesKey = "{\"key\": \"qwertasdfgzxcvbn\", \"iv\": \"bvcxzgfdsatrewqy\"}";
System.out.println("\n========== Original Data ==========");
System.out.println("param: " + param);
System.out.println("aesKey: " + aesKey);
// 0. Use AES to encrypt param content
System.out.println("\n========== 0. AES Encryption and Decryption ==========");
JSONObject aesKeyJson = JSON.parseObject(aesKey);
String key = aesKeyJson.getString("key");
String iv = aesKeyJson.getString("iv");
// Create AES encrypter (CBC mode, PKCS5Padding)
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv.getBytes());
// Encrypt param
String encryptedParam = aes.encryptBase64(param);
System.out.println("AES encrypted param: " + encryptedParam);
// Decrypt and verify
String decryptedParam = aes.decryptStr(encryptedParam);
System.out.println("AES decrypted param: " + decryptedParam);
System.out.println("AES encryption/decryption verification: " + (param.equals(decryptedParam) ? "✓ Success" : "✗ Failed"));
// 1. Use RSA private key to sign param and verify the signature
System.out.println("\n========== 1. RSA Signature and Verification ==========");
String sign = generateSign(param, PRIVATE_KEY);
System.out.println("Generated signature: " + sign);
boolean verifyResult = verifySign(param, sign, PUBLIC_KEY);
System.out.println("Signature verification result: " + (verifyResult ? "✓ Passed" : "✗ Failed"));
// 2. Use RSA private key to encrypt aesKey and decrypt/verify the data
System.out.println("\n========== 2. RSA Encryption and Decryption ==========");
String encryptedAesKey = encryptWithPrivateKey(aesKey, PRIVATE_KEY);
System.out.println("Encrypted aesKey: " + encryptedAesKey);
String decryptedAesKey = decryptWithPublicKey(encryptedAesKey, PUBLIC_KEY);
System.out.println("Decrypted aesKey: " + decryptedAesKey);
System.out.println("Decryption verification: " + (aesKey.equals(decryptedAesKey) ? "✓ Success" : "✗ Failed"));
} catch (Exception e) {
System.err.println("Error occurred: " + e.getMessage());
e.printStackTrace();
}
}
}
# Response Parameters
| Parameter Name | Type | Description |
|---|---|---|
| code | integer | response code |
| message | string | response message |
| data | Object | data |
# data Parameters
| Parameter Name | Type | Description |
|---|---|---|
| expireSeconds | int | 3600 seconds (expiration time) |
| authUrl | string | Password-free login URL |
| accountNo | string | Wallet user account (unique identifier for wallet-side user) |
| token | string | Wallet user login token |
# Response Example
# Response Body
{
"code": 1000,
"message": "success",
"data": {
"expireSeconds": 3600,
"authUrl": "https://www.paycools.com.ph/#/splash?token=V0xUX1VTRVI6YTBiMjliZmItMzAxMy00ZWVjLTkzY2QtMGRiMzJcYjUxNmUx",
"accountNo": "2200636699666629",
"token": "V0xUX1VTRVI6ZjQ4NjdkYjQtYzAxYy00OTNmLWJhODEtM2Q3MWU1NTM3NmFm"
}
}
# Response Failure Case see reference
{
"code":1002,
"message":"merchant white ip forbidden"
}