接入说明 #

参考流程 #

相关术语 #

术语 说明
电子发票 指经营活动中开具或收取的数据电文形式的收付款凭证,即传统发票的电子版。
数电票 全面数字化的电子发票,是一种全新的发票形式,具有与纸质发票同等的法律效力。
电子行程单 亦称为航空运输电子客票行程单,它既是旅客购买电子客票的支付凭证,也是报销凭证,可以将其视作一种特殊样式的数电票,同样可作为报销依据。
机票款 机票已使用时开具的款项,费用明细包含机票票价+改期变更手续费*+税费(机建*、燃油、国际税费)。
退票款 机票已退订时开具的款项,费用明细包含退票手续费+改期变更手续费。
附加服务款 购买附加服务之后可开具的款项,目前支持行李、选座、升舱、餐食、休息室等辅营产品。
红字发票 纠正已开具发票错误的特殊发票,具有冲销功能。

加密算法 #


  private static final Charset CHARSET = StandardCharsets.UTF_8;

  private static final String KEY_ALGORITHM = "AES";
  /**
   * 签名算法
   */
  public static final String SIGN_ALGORITHMS = "SHA1PRNG";

  private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法

  private static final int KEY_LENGTH = 128;

  /**
   * AES 加密操作
   *
   * @param content 待加密内容
   * @param key     加密密钥
   * @return 返回Base64转码后的加密数据
   */
  public static String encrypt(String content, String key) throws Exception {
    // 创建密码器
    Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

    byte[] byteContent = content.getBytes(CHARSET);

    // 初始化为加密模式的密码器
    cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));

    // 加密
    byte[] result = cipher.doFinal(byteContent);

    //通过Base64转码返回
    return Base64Util.encryptBASE64(result);
  }

  /**
   * AES 解密操作
   *
   * @param content
   * @param key
   * @return
   */
  public static String decrypt(String content, String key) throws Exception {
    //实例化
    Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    //使用密钥初始化,设置为解密模式
    cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));

    //执行操作
    byte[] result = cipher.doFinal(Base64Util.decryptBASE64(content));


    return new String(result, CHARSET);
  }

  /**
   * 生成加密秘钥
   *
   * @return
   */
  private static SecretKeySpec getSecretKey(final String key) throws NoSuchAlgorithmException {
    //返回生成指定算法密钥生成器的 KeyGenerator 对象
    KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);

    SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
    random.setSeed(key.getBytes(CHARSET));

    //AES 要求密钥长度为 128
    kg.init(KEY_LENGTH, random);

    //生成一个密钥
    SecretKey secretKey = kg.generateKey();
    //// 转换为AES专用密钥
    return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
  }

示例

==> 明文入参

{
  "issueInvoiceInfo": {
    "invoiceHeader": {
      "invoiceHeaderType": "BUSINESS",
      "headerName": "厦门航空有限公司虚拟单位",
      "taxNo": "91XXXX000000XXXXD",
      "telNo": "15659811111",
      "email": "329666666@qq.com",
      "remarks": ""
    },
    "ticketFeeList": [
      {
        "ticketNo": "7312100105580",
        "psgName": "CANGMU/MAYITEST",
        "productType": "Flight",
        "feeType": "REFUND_FEE"
      }
    ]
  }
}


==> 请求入参加密


curl --location --request POST 'invoice/issueInvoice' \
--header 'Content-Type: application/json' \
--header 'agency: 12306' \
--header 'APIKEY: ' \
--data-raw '"BIENcNL66Uj0noKNCutK7MKOu325Ut0B/+GYJVzEmT7WhcrhaJOgkuryTvFY5IeEPzDihArVogbSukYBzpAm13V2kdwMVAo5r6Wx6eQTk95OebKbYapuHtRyp+V8kTi16PNKaAQq5K7XafwiQl9boSLzlfBNPYzSpBjW7lyb9MTF/qs070K5FlD0eb7Ib353Gqt0wHxRAstQpuH7fqsl4JGd00ssGmdMK/fcYQoM8Sues7/RIVb/lYFWPFXfxA6YgES+3t4yVc7Md8taKuvM6CBkv3j+bCv/2lhjgqpkIagrYam4wSXqGuzk2jzXAmxucVpeB0swsyqrvdMNsa0IUBN/kKi7tVrb1+GHtAtkavtlg5ao10+XAsC+9RII/CQKJIh5SKXXV0BIdNmd9NcDB2fd/DXN2vIodNhFv/HSEK9Jp8+mPO0IQmhNqeaZJ4O0"
'
        
==> 密文出参
        
{
    "code": 200,
    "message": "success",
    "data": "NkH2FIaorydo6gzVxXW3baxsxMrf9aDmw2eChM64VDm/hTWyKf/fMMPo43gsMCU7mR2ziD/AozVh0kJLLkPqeVJUxiyxTHb7LGh81MK7tHlxGDsBU3J20eD4HdOnTKOw",
    "traceId": "6d9ec9d4259e37d9"
}

==> 密文解密

        
{
    "code": 200,
    "message": "success",
    "data": {
        "success": true,
        "errInfo": "发票请求接收成功",
        "invoiceId": "202411291021472532"
    },
    "traceId": "6d9ec9d4259e37d9"
}

注意事项 #

  1. 入参需要进行AES加密,以字符串形式传入,出参的data需要进行AES解密,文档示例均为明文。

  2. 由于税局限制代收民航发展基金(机建费)与其他非机票款项同时开具数电票,故厦航限制机票款与其他款项同时开具。

  3. 国内单张发票限额10000,国际单张发票限额100000。

  4. 机票仅已使用或已退票才允许开具电子发票。

  5. 机票款需在机票使用后一年内申请,退票款需在退票审核通过后申请,附加服务需在购买后一年内申请。

  6. 机票款的报销凭证只能选择发票和行程单的一种,不可重复开具。