import EasySDKKernel;

type @kernel = EasySDKKernel

init(kernel: EasySDKKernel) {
  @kernel = kernel;
}

model TradeFundBill {
  fundChannel: string(name='fund_channel'),
  bankCode: string(name='bank_code'),
  amount: string(name='amount'),
  realAmount: string(name='real_amount')
}

model VoucherDetail {
  id: string(name='id'),
  name: string(name='name'),
  type: string(name='type'),
  amount: string(name='amount'),
  merchantContribute: string(name='merchant_contribute'),
  otherContribute: string(name='other_contribute'),
  memo: string(name='memo'),
  templateId: string(name='template_id'),
  purchaseBuyerContribute: string(name='purchase_buyer_contribute'),
  purchaseMerchantContribute: string(name='purchase_merchant_contribute'),
  purchaseAntContribute: string(name='purchase_ant_contribute')
}

model AlipayTradePayResponse {
  httpBody: string(name='http_body', description='响应原始字符串'),
  code: string(name='code'),
  msg: string(name='msg'),
  subCode: string(name='sub_code'),
  subMsg: string(name='sub_msg'),

  tradeNo: string(name='trade_no'),
  outTradeNo: string(name='out_trade_no'),
  buyerLogonId: string(name='buyer_logon_id'),
  settleAmount: string(name='settle_amount'),
  payCurrency: string(name='pay_currency'),
  payAmount: string(name='pay_amount'),
  settleTransRate: string(name='settle_trans_rate'),
  transPayRate: string(name='trans_pay_rate'),
  totalAmount: string(name='total_amount'),
  transCurrency: string(name='trans_currency'),
  settleCurrency: string(name='settle_currency'),
  receiptAmount: string(name='receipt_amount'),
  buyerPayAmount: string(name='buyer_pay_amount'),
  pointAmount: string(name='point_amount'),
  invoiceAmount: string(name='invoice_amount'),
  gmtPayment: string(name='gmt_payment'),
  fundBillList: [ TradeFundBill ](name='fund_bill_list'),
  cardBalance: string(name='card_balance'),
  storeName: string(name='store_name'),
  buyerUserId: string(name='buyer_user_id'),
  discountGoodsDetail: string(name='discount_goods_detail'),
  voucherDetailList: [ VoucherDetail ](name='voucher_detail_list'),
  advanceAmount: string(name='advance_amount'),
  authTradePayMode: string(name='auth_trade_pay_mode'),
  chargeAmount: string(name='charge_amount'),
  chargeFlags: string(name='charge_flags'),
  settlementId: string(name='settlement_id'),
  businessParams: string(name='business_params'),
  buyerUserType: string(name='buyer_user_type'),
  mdiscountAmount: string(name='mdiscount_amount'),
  discountAmount: string(name='discount_amount'),
  buyerUserName: string(name='buyer_user_name')
}

model AlipayTradePrecreateResponse {
  httpBody: string(name='http_body', description='响应原始字符串'),
  code: string(name='code'),
  msg: string(name='msg'),
  subCode: string(name='sub_code'),
  subMsg: string(name='sub_msg'),

  outTradeNo: string(name='out_trade_no'),
  qrCode: string(name='qr_code'),
}


api pay(subject: string, outTradeNo: string, totalAmount: string, authCode: string): AlipayTradePayResponse {
  var systemParams: map[string]string = {
    method = 'alipay.trade.pay',
    app_id = @kernel.getConfig("appId"),
    timestamp = @kernel.getTimestamp(),
    format = 'json',
    version = '1.0',
    alipay_sdk = @kernel.getSdkVersion(),
    charset = 'UTF-8',
    sign_type = @kernel.getConfig("signType"),
    app_cert_sn = @kernel.getMerchantCertSN(),
    alipay_root_cert_sn = @kernel.getAlipayRootCertSN()
  };

  var bizParams: map[string]any = {
    subject = subject,
    out_trade_no = outTradeNo,
    total_amount = totalAmount,
    auth_code = authCode,
    scene = 'bar_code'
  };

  var textParams: map[string]string = {
  };

  __request.protocol = @kernel.getConfig("protocol");
  __request.method = 'POST';
  __request.pathname = '/gateway.do';

  __request.headers = {
    host = @kernel.getConfig("gatewayHost"),
    content-type = 'application/x-www-form-urlencoded;charset=utf-8'
  };

  __request.query = @kernel.sortMap({
    sign = @kernel.sign(systemParams, bizParams, textParams, @kernel.getConfig("merchantPrivateKey")),
    ... systemParams,
    ... textParams
  });

  __request.body = @kernel.toUrlEncodedRequestBody(bizParams);
} returns {
  var respMap: map[string]any = @kernel.readAsJson(__response, "alipay.trade.pay");

  if (@kernel.isCertMode()) {
    if (@kernel.verify(respMap, @kernel.extractAlipayPublicKey(@kernel.getAlipayCertSN(respMap)))) {
      return @kernel.toRespModel(respMap);
    }
  } else {
    if (@kernel.verify(respMap, @kernel.getConfig("alipayPublicKey"))) {
      return @kernel.toRespModel(respMap);
    }
  }
  
  throw {
    message = '验签失败，请检查支付宝公钥设置是否正确。'
  }
  
} runtime {
  ignoreSSL = @kernel.getConfig("ignoreSSL"),
  httpProxy = @kernel.getConfig("httpProxy"),
  connectTimeout = 15000,
  readTimeout = 15000,
  retry = {
    maxAttempts = 0
  }
}

api preCreate(subject: string, outTradeNo: string, totalAmount: string): AlipayTradePrecreateResponse {
  var systemParams: map[string]string = {
    method = 'alipay.trade.precreate',
    app_id = @kernel.getConfig("appId"),
    timestamp = @kernel.getTimestamp(),
    format = 'json',
    version = '1.0',
    alipay_sdk = @kernel.getSdkVersion(),
    charset = 'UTF-8',
    sign_type = @kernel.getConfig("signType"),
    app_cert_sn = @kernel.getMerchantCertSN(),
    alipay_root_cert_sn = @kernel.getAlipayRootCertSN()
  };

  var bizParams: map[string]any = {
    subject = subject,
    out_trade_no = outTradeNo,
    total_amount = totalAmount
  };

  var textParams: map[string]string = {
  };

  __request.protocol = @kernel.getConfig("protocol");
  __request.method = 'POST';
  __request.pathname = '/gateway.do';

  __request.headers = {
    host = @kernel.getConfig("gatewayHost"),
    content-type = 'application/x-www-form-urlencoded;charset=utf-8'
  };

  __request.query = @kernel.sortMap({
    sign = @kernel.sign(systemParams, bizParams, textParams, @kernel.getConfig("merchantPrivateKey")),
    ... systemParams,
    ... textParams
  });

  __request.body = @kernel.toUrlEncodedRequestBody(bizParams);
} returns {
  var respMap: map[string]any = @kernel.readAsJson(__response, "alipay.trade.precreate");

  if (@kernel.isCertMode()) {
    if (@kernel.verify(respMap, @kernel.extractAlipayPublicKey(@kernel.getAlipayCertSN(respMap)))) {
      return @kernel.toRespModel(respMap);
    }
  } else {
    if (@kernel.verify(respMap, @kernel.getConfig("alipayPublicKey"))) {
      return @kernel.toRespModel(respMap);
    }
  }

  throw {
    message = '验签失败，请检查支付宝公钥设置是否正确。'
  }

} runtime {
  ignoreSSL = @kernel.getConfig("ignoreSSL"),
  httpProxy = @kernel.getConfig("httpProxy"),
  connectTimeout = 15000,
  readTimeout = 15000,
  retry = {
    maxAttempts = 0
  }
}
