合作伙伴活动服务 #
合作伙伴活动报名(支持非会员) #
说明
1、传输对敏感字段进行 AES256加密,如第三方无强制要求则对加密方式不做调整
2、AES256的密钥由厦航分配
3、请求参数中的 channe、source 无特殊情况传输默认值,actInfoid由厦航提供
请求方式 POST
consumes ["application/json"]
produces ["*/*"]
接口描述 ``
请求参数
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | 备注 |
|---|---|---|---|---|---|
| channel | 渠道ID | header | true | string | 默认传 M_WEBSITE |
| request | 扩展注册请求 | body | true | RegisterExtRequest对象 | RegisterExtRequest对象 |
schema属性说明
RegisterExtRequest对象
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | 备注 |
|---|---|---|---|---|---|
| actInfoId | 活动ID | body | true | integer(int64) | |
| certNo | 证件号 | body | true | string | AES加密 |
| certTpcd | 证件类型代码(01:身份证02:护照 07:港澳居住证 08:台湾居住证 99:其他证件) | body | true | string | |
| chnName | 中文姓名 | body | false | string | 中文姓名和英文姓名不可以都为空 |
| givenName | 英文名 | body | false | string | |
| surName | 英文姓 | body | false | string | |
| phone | 手机号 | body | true | string | AES加密,秘钥由厦航提供 |
| source | 用户注册渠道 | body | true | string | 默认传ACTIVITY |
响应状态
| 状态码 | 说明 | schema |
|---|---|---|
| 200 | OK | ResultBean«RegisterExtResponse对象» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found |
响应参数
| 参数名称 | 参数说明 | 类型 | schema |
|---|---|---|---|
| code | 返回码:0表示成功 | integer(int32) | integer(int32) |
| msg | 业务提示语:前端可展示的提示内容, 如:"找不到您的航班" | string | |
| result | RegisterExtResponse对象 | RegisterExtResponse对象 | |
| success | boolean | ||
| tip | 技术性提示语: 第三方错误的原始内容, 如: no_offer_for_request | string | |
| traceId | 用于日志追踪:traceId | string |
code场景说明
| code | 使用场景 |
|---|---|
| 201 | 参数错误,传参未按照约定处理 |
| 4_00_101 | 符合注册条件,但用户中心注册失败 |
| 4_00_108 | 用户信息有误(如证件号一致但手机号不一致等情况),无法报名 |
| 4_00_201 | 未找到活动 |
| 4_00_202 | 活动无效 |
| 4_00_203 | 活动未上线或者已下线 |
| 4_00_204 | 活动不在有效期 |
schema属性说明
RegisterExtResponse对象
| 参数名称 | 参数说明 | 类型 | schema |
|---|---|---|---|
| egretCardNo | 白鹭卡号 | string | |
| result | 报名结果 | boolean |
响应示例
{
"code": 0,
"msg": "",
"result": {
"egretCardNo": "",
"result": true
},
"success": true,
"tip": "",
"traceId": ""
}
加密参考
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AES256 {
static String Encrypt(String key, String text) {
try {
byte[] cipher = Encrypt(key.getBytes(), text.getBytes());
return new BASE64Encoder().encode(cipher);
} catch (Exception e) {
return "";
}
}
static String Decrypt(String key, String cipher) {
try {
BASE64Decoder base64de = new BASE64Decoder();
byte[] cipherBytes = base64de.decodeBuffer(cipher);
byte[] text = Decrypt(key.getBytes(), cipherBytes);
return new String(text);
} catch (Exception e) {
return "";
}
}
static byte[] Encrypt(byte[] key, byte[] text) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] aesKeyBytes = new byte[32]; //32 bytes for AES-256
int len = key.length > 32 ? 32 : key.length;
System.arraycopy(key, 0, aesKeyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(aesKeyBytes, "AES");
byte[] iv = new byte[cipher.getBlockSize()];
Random ran = new Random();
ran.nextBytes(iv); //随机的初始化向量
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] results = cipher.doFinal(text);
//将iv和密文拼接后返回
byte[] retBytes = new byte[iv.length + results.length];
System.arraycopy(iv, 0, retBytes, 0, iv.length);
System.arraycopy(results, 0, retBytes, iv.length, results.length);
return retBytes;
} catch (Exception e) {
return null;
}
}
static byte[] Decrypt(byte[] key, byte[] cipher) {
try {
if (cipher.length < 32 || cipher.length % 16 != 0) {
return null;
}
Cipher cp = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] aesKeyBytes = new byte[32]; //32 bytes for AES-256
int len = key.length > 32 ? 32 : key.length;
System.arraycopy(key, 0, aesKeyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(aesKeyBytes, "AES");
byte[] iv = new byte[cp.getBlockSize()];
//将iv和密文拼接后返回
System.arraycopy(cipher, 0, iv, 0, iv.length);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cp.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] cip = new byte[cipher.length - iv.length];
System.arraycopy(cipher, iv.length, cip, 0, cip.length);
byte[] results = cp.doFinal(cip);
return results;
} catch (Exception e) {
return null;
}
}
}
测试代码
@Test
public void fun() {
System.out.println("Test aes 256");
String key = "123";
String plain = "123456";
String cipher = AES256.Encrypt(key, plain);
System.out.println("明文: " + plain);
System.out.println("加密后: " + cipher);
String plain1 = AES256.Decrypt(key, cipher);
System.out.println("解密后: " + plain1);
}
合作伙伴活动报名(仅支持厦航会员) #
说明
请求参数中的 channe无特殊情况传输默认值,actInfoid由厦航提供
请求方式 POST
consumes ["application/json"]
produces ["*/*"]
接口描述 ``
请求参数
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | 备注 |
|---|---|---|---|---|---|
| channel | 渠道ID | header | true | string | 默认传 M_WEBSITE |
| request | request | body | true | InnerRegisterRequest | InnerRegisterRequest |
schema属性说明
InnerRegisterRequest
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema |
|---|---|---|---|---|---|
| actInfoId | 活动ID | body | true | integer(int64) | |
| egretCardNo | 白鹭卡号 | body | true | string | |
| inputTime | 插入时间 | body | true | string(date-time) | |
| redictSource | 引流来源 | body | false | string | |
| registerType | 报名类型(0:被邀请,1:主动报名,2:引流,3:扫码,4:其他活动关联报名) | body | true | integer(int32) | |
| userId | userId | body | false | string | |
| username | 用户名 | body | false | string |
响应状态
| 状态码 | 说明 | schema |
|---|---|---|
| 200 | OK | ResultBean«RegisterResponse对象» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found |
响应参数
| 参数名称 | 参数说明 | 类型 | schema |
|---|---|---|---|
| code | 返回码:0表示成功 | integer(int32) | integer(int32) |
| msg | 业务提示语:前端可展示的提示内容, 如:"找不到您的航班" | string | |
| result | RegisterResponse对象 | RegisterResponse对象 | |
| success | boolean | ||
| tip | 技术性提示语: 第三方错误的原始内容, 如: no_offer_for_request | string | |
| traceId | 用于日志追踪:traceId | string |
schema属性说明
RegisterResponse对象
| 参数名称 | 参数说明 | 类型 | schema |
|---|---|---|---|
| egretCardNo | 编码后的白鹭卡号 | string | |
| isFirstRegister | 是否首次注册 | boolean |
响应示例
{
"code": 0,
"msg": "",
"result": {
"egretCardNo": "",
"isFirstRegister": true
},
"success": true,
"tip": "",
"traceId": ""
}