use serde::{Deserialize, Serialize};
use serde_json::{Value};
use crate::{Amount, errors::LabraError, GoodsDetail, LabradorResult, Payer, RefundAmount, SceneInfo, TradeType};
use crate::util::{get_nonce_str, get_timestamp, xmlutil};
use crate::wechat::cryptos::{EncryptV3, WechatCrypto, WechatCryptoV3};
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatPayResponse {
pub appid: Option<String>,
pub trade_type: String,
pub mch_id: String,
pub openid: String,
pub sign: String,
pub nonce_str: Option<String>,
pub prepay_id: Option<String>,
pub result_code: String,
pub code_url: Option<String>,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
pub mweb_url: Option<String>,
pub transaction_id: Option<String>,
}
#[allow(unused)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlatformCertificateResponse {
pub effective_time: String,
pub expire_time: String,
pub encrypt_certificate: EncryptV3,
pub serial_no: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatPayResponseV3 {
pub prepay_id: Option<String>,
pub h5_url: Option<String>,
pub code_url: Option<String>,
}
impl WechatPayResponseV3 {
pub fn get_pay_info(&self, trade_type: TradeType, appid: Option<String>, mchid: String, private_key: Option<String>) -> LabradorResult<Value> {
let timpstamp = get_timestamp() / 1000;
let nonce_str = get_nonce_str();
let private_key= private_key.unwrap_or_default();
let appid = appid.unwrap_or_default();
match trade_type {
TradeType::MWeb => {
Ok(Value::String(self.h5_url.to_owned().unwrap_or_default()))
}
TradeType::Jsapi => {
let mut result = JsapiResult {
app_id: appid.to_owned(),
time_stamp: timpstamp.to_string(),
nonce_str,
prepay_id: self.prepay_id.to_owned().unwrap_or_default(),
package: format!("prepay_id={}", self.prepay_id.to_owned().unwrap_or_default()),
sign_type: "RSA".to_string(), pay_sign: String::default()
};
result.pay_sign = WechatCryptoV3::sign(&result.get_sign_str(), &private_key)?;
Ok(serde_json::to_value(result)?)
}
TradeType::Native => {
Ok(Value::String(self.code_url.to_owned().unwrap_or_default()))
}
TradeType::App => {
let mut result = AppResult {
partner_id: mchid,
appid: appid.to_owned(),
time_stamp: timpstamp.to_string(),
nonce_str,
package_value: format!("Sign=WXPay"),
prepay_id: self.prepay_id.to_owned().unwrap_or_default(),
sign: "".to_string()
};
result.sign = WechatCryptoV3::sign(&result.get_sign_str(), &private_key)?;
Ok(serde_json::to_value(result)?)
}
_ => Err(LabraError::RequestError("不支持的支付类型".to_string()))
}
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsapiResult {
app_id: String,
time_stamp: String,
nonce_str: String,
package: String,
sign_type: String,
pay_sign: String,
prepay_id: String,
}
impl JsapiResult {
pub fn get_sign_str(&self) -> String {
format!("{}\n{}\n{}\n{}\n", self.app_id, self.time_stamp, self.nonce_str, self.package)
}
}
#[derive(Serialize, Deserialize)]
pub struct AppResult {
appid: String,
partner_id: String,
prepay_id: String,
time_stamp: String,
nonce_str: String,
package_value: String,
sign: String,
}
impl AppResult {
pub fn get_sign_str(&self) -> String {
format!("{}\n{}\n{}\n{}\n", self.appid, self.time_stamp, self.nonce_str, self.prepay_id)
}
}
#[allow(unused)]
impl WechatPayResponse {
pub(crate) fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let trade_type = xmlutil::evaluate(&doc, "//xml/trade_type/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let openid = xmlutil::evaluate(&doc, "//xml/openid/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let prepay_id = xmlutil::evaluate(&doc, "//xml/prepay_id/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
let code_url = xmlutil::evaluate(&doc, "//xml/code_url/text()").string();
let mweb_url = xmlutil::evaluate(&doc, "//xml/mweb_url/text()").string();
let transaction_id = xmlutil::evaluate(&doc, "//xml/transaction_id/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
Ok(WechatPayResponse {
appid: appid.into(),
trade_type,
mch_id,
openid,
sign: sign.into(),
nonce_str: nonce_str.into(),
prepay_id: prepay_id.into(),
result_code,
code_url: code_url.into(),
err_code: err_code.into(),
err_code_des: err_code_des.into(),
mweb_url: mweb_url.into(),
transaction_id: transaction_id.into(),
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatCloseOrderResponse {
pub appid: Option<String>,
pub mch_id: String,
pub sign: String,
pub nonce_str: Option<String>,
pub result_code: String,
pub return_code: String,
pub return_msg: String,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
}
impl WechatCloseOrderResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
Ok(WechatCloseOrderResponse {
appid: appid.into(),
nonce_str: nonce_str.into(),
mch_id,
return_code,
sign,
err_code: err_code.into(),
err_code_des: err_code_des.into(),
return_msg,
result_code,
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct PromotionDetail {
pub coupon_id: String,
pub amount: i64,
pub name: Option<String>,
pub stock_id: Option<String>,
pub wechatpay_contribute: Option<i64>,
pub merchant_contribute: Option<i64>,
pub other_contribute: Option<i64>,
pub currency: Option<String>,
pub scope: Option<String>,
pub goods_detail: Option<GoodsDetail>,
#[serde(rename="type")]
pub r#type: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RefundPromotionDetail {
pub promotion_id: String,
pub scope: Option<String>,
#[serde(rename="type")]
pub r#type: Option<String>,
pub amount: i64,
pub refund_amount: i64,
pub goods_detail: Option<GoodsDetail>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatQueryOrderResponseV3 {
pub appid: String,
pub mch_id: String,
pub out_trade_no: String,
pub trade_type: String,
pub transaction_id: String,
pub trade_state: String,
pub trade_state_desc: String,
pub bank_type: String,
pub attach: Option<String>,
pub success_time: String,
pub payer: Payer,
pub amount: Option<Amount>,
pub scene_info: Option<SceneInfo>,
pub promotion_detail: Option<PromotionDetail>,
pub fee_type: Option<String>,
pub total_fee: i64,
pub settlement_total_fee: Option<i64>,
pub coupon_fee: Option<i64>,
pub coupon_count: Option<i64>,
pub cash_fee: i64,
pub cash_fee_type: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatQueryOrderResponse {
pub appid: Option<String>,
pub mch_id: String,
pub sign: String,
pub nonce_str: Option<String>,
pub result_code: String,
pub return_code: String,
pub return_msg: String,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
pub promotion_detail: Option<String>,
pub device_info: Option<String>,
pub openid: String,
pub is_subscribe: String,
pub sub_openid: Option<String>,
pub trade_type: String,
pub trade_state: String,
pub bank_type: String,
pub transaction_id: String,
pub out_trade_no: String,
pub time_end: String,
pub trade_state_desc: String,
pub detail: Option<String>,
pub attach: Option<String>,
pub fee_type: Option<String>,
pub total_fee: i64,
pub settlement_total_fee: Option<i64>,
pub coupon_fee: Option<i64>,
pub coupon_count: Option<i64>,
pub cash_fee: i64,
pub cash_fee_type: Option<String>,
}
impl WechatQueryOrderResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
let promotion_detail = xmlutil::evaluate(&doc, "//xml/promotion_detail/text()").string();
let device_info = xmlutil::evaluate(&doc, "//xml/device_info/text()").string();
let openid = xmlutil::evaluate(&doc, "//xml/openid/text()").string();
let is_subscribe = xmlutil::evaluate(&doc, "//xml/is_subscribe/text()").string();
let sub_openid = xmlutil::evaluate(&doc, "//xml/sub_openid/text()").string();
let trade_type = xmlutil::evaluate(&doc, "//xml/trade_type/text()").string();
let trade_state = xmlutil::evaluate(&doc, "//xml/trade_state/text()").string();
let bank_type = xmlutil::evaluate(&doc, "//xml/bank_type/text()").string();
let transaction_id = xmlutil::evaluate(&doc, "//xml/transaction_id/text()").string();
let out_trade_no = xmlutil::evaluate(&doc, "//xml/out_trade_no/text()").string();
let time_end = xmlutil::evaluate(&doc, "//xml/time_end/text()").string();
let trade_state_desc = xmlutil::evaluate(&doc, "//xml/trade_state_desc/text()").string();
let detail = xmlutil::evaluate(&doc, "//xml/detail/text()").string();
let attach = xmlutil::evaluate(&doc, "//xml/attach/text()").string();
let fee_type = xmlutil::evaluate(&doc, "//xml/fee_type/text()").string();
let total_fee = xmlutil::evaluate(&doc, "//xml/total_fee/text()").string();
let settlement_total_fee = xmlutil::evaluate(&doc, "//xml/settlement_total_fee/text()").string();
let coupon_fee = xmlutil::evaluate(&doc, "//xml/coupon_fee/text()").string();
let coupon_count = xmlutil::evaluate(&doc, "//xml/coupon_count/text()").string();
let cash_fee = xmlutil::evaluate(&doc, "//xml/cash_fee/text()").string();
let cash_fee_type = xmlutil::evaluate(&doc, "//xml/cash_fee_type/text()").string();
Ok(WechatQueryOrderResponse {
appid: appid.into(),
nonce_str: nonce_str.into(),
mch_id,
return_code,
sign,
err_code: err_code.into(),
err_code_des: err_code_des.into(),
promotion_detail: promotion_detail.into(),
device_info: device_info.into(),
openid,
is_subscribe,
sub_openid: sub_openid.into(),
trade_type,
trade_state,
bank_type,
transaction_id,
out_trade_no,
time_end,
trade_state_desc,
detail: detail.into(),
attach: attach.into(),
fee_type: fee_type.into(),
total_fee: total_fee.parse::<i64>().unwrap_or_default(),
settlement_total_fee: settlement_total_fee.parse::<i64>().unwrap_or_default().into(),
coupon_fee: coupon_fee.parse::<i64>().unwrap_or_default().into(),
coupon_count: coupon_count.parse::<i64>().unwrap_or_default().into(),
cash_fee: cash_fee.parse::<i64>().unwrap_or_default(),
return_msg,
result_code,
cash_fee_type: cash_fee_type.into()
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatRefundResponseV3 {
pub refund_id: String,
pub out_trade_no: String,
pub transaction_id: String,
pub out_refund_no: String,
pub channel: String,
pub user_received_account: String,
pub success_time: Option<String>,
pub create_time: String,
pub status: String,
pub funds_account: Option<String>,
pub amount : RefundAmount,
pub promotion_detail : Option<Vec<RefundPromotionDetail>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatRefundResponse {
pub appid: Option<String>,
pub mch_id: String,
pub sign: String,
pub transaction_id: String,
pub out_trade_no: String,
pub out_refund_no: String,
pub refund_id: String,
pub nonce_str: Option<String>,
pub refund_channel: Option<String>,
pub result_code: String,
pub return_code: String,
pub return_msg: String,
pub refund_fee: String,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatOrderReverseResponse {
pub appid: Option<String>,
pub mch_id: String,
pub sign: String,
pub recall: String,
pub nonce_str: Option<String>,
pub result_code: String,
pub return_code: String,
pub return_msg: String,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
}
impl WechatOrderReverseResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let recall = xmlutil::evaluate(&doc, "//xml/recall/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
if result_code.eq("SUCCESS") {
Ok(WechatOrderReverseResponse {
appid: appid.into(),
nonce_str: nonce_str.into(),
mch_id,
return_code,
sign,
err_code: err_code.into(),
err_code_des: err_code_des.into(),
return_msg,
result_code,
recall
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: err_code_des})
}
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
impl WechatRefundResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let transaction_id = xmlutil::evaluate(&doc, "//xml/transaction_id/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let out_trade_no = xmlutil::evaluate(&doc, "//xml/out_trade_no/text()").string();
let out_refund_no = xmlutil::evaluate(&doc, "//xml/out_refund_no/text()").string();
let refund_id = xmlutil::evaluate(&doc, "//xml/refund_id/text()").string();
let refund_channel = xmlutil::evaluate(&doc, "//xml/refund_channel/text()").string();
let refund_fee = xmlutil::evaluate(&doc, "//xml/refund_fee/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
if result_code.eq("SUCCESS") {
Ok(WechatRefundResponse {
appid: appid.into(),
nonce_str: nonce_str.into(),
mch_id,
return_code,
sign,
err_code: err_code.into(),
err_code_des: err_code_des.into(),
return_msg,
result_code,
transaction_id,
out_trade_no,
out_refund_no,
refund_id,
refund_channel: refund_channel.into(),
refund_fee,
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: err_code_des})
}
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatQueryRefundResponse {
pub appid: Option<String>,
pub mch_id: String,
pub sign: String,
pub transaction_id: String,
pub out_trade_no: String,
pub total_fee: i64,
pub settlement_total_fee: Option<i64>,
pub fee_type: Option<String>,
pub cash_fee: i64,
pub refund_count: i64,
pub promotion_detail: Option<String>,
pub nonce_str: Option<String>,
pub result_code: String,
pub return_code: String,
pub return_msg: String,
pub refund_fee: String,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
}
impl WechatQueryRefundResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let transaction_id = xmlutil::evaluate(&doc, "//xml/transaction_id/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let out_trade_no = xmlutil::evaluate(&doc, "//xml/out_trade_no/text()").string();
let refund_fee = xmlutil::evaluate(&doc, "//xml/refund_fee/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
let total_fee = xmlutil::evaluate(&doc, "//xml/total_fee/text()").string();
let settlement_total_fee = xmlutil::evaluate(&doc, "//xml/settlement_total_fee/text()").string();
let fee_type = xmlutil::evaluate(&doc, "//xml/fee_type/text()").string();
let cash_fee = xmlutil::evaluate(&doc, "//xml/cash_fee/text()").string();
if result_code.eq("SUCCESS") {
Ok(WechatQueryRefundResponse {
appid: appid.into(),
nonce_str: nonce_str.into(),
mch_id,
return_code,
sign,
err_code: err_code.into(),
err_code_des: err_code_des.into(),
return_msg,
result_code,
transaction_id,
out_trade_no,
total_fee: total_fee.parse::<i64>().unwrap_or_default(),
settlement_total_fee: settlement_total_fee.parse::<i64>().unwrap_or_default().into(),
fee_type: fee_type.into(),
cash_fee: cash_fee.parse::<i64>().unwrap_or_default(),
refund_count: 0,
refund_fee,
promotion_detail: None
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: err_code_des})
}
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatQueryRefundResponseV3 {
pub refund_id: String,
pub transaction_id: String,
pub out_refund_no: String,
pub out_trade_no: String,
pub channel: Option<String>,
pub user_received_account: String,
pub success_time: Option<String>,
pub create_time: String,
pub status: String,
pub funds_account: Option<String>,
pub amount: RefundAmount,
pub promotion_detail: Option<Vec<RefundPromotionDetail>>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WechatPayNotifyResponse {
pub appid: Option<String>,
pub trade_type: String,
pub bank_type: Option<String>,
pub fee_type: Option<String>,
pub is_subscribe: Option<String>,
pub nonce_str: Option<String>,
pub mch_id: String,
pub openid: String,
pub out_trade_no: String,
pub return_code: String,
pub sign: String,
pub time_end: String,
pub total_fee: String,
pub cash_fee: String,
pub coupon_fee: Option<String>,
pub coupon_count: Option<String>,
pub coupon_type: Option<String>,
pub coupon_id: Option<String>,
pub transaction_id: String,
pub attach: Option<String>,
pub result_code: String,
pub return_msg: String,
pub err_code: Option<String>,
pub err_code_des: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WechatPayNotifyResponseV3 {
pub raw_data: Option<OriginNotifyResponse>,
pub result: Option<DecryptNotifyResult>,
}
impl WechatPayNotifyResponseV3 {
pub fn decrypt_result(&self) -> DecryptNotifyResult {
if let Some(res) = self.result.to_owned() {
res
} else {
DecryptNotifyResult {
appid: "".to_string(),
mchid: "".to_string(),
out_trade_no: "".to_string(),
transaction_id: "".to_string(),
trade_type: "".to_string(),
trade_state: "".to_string(),
trade_state_desc: "".to_string(),
bank_type: "".to_string(),
attach: None,
success_time: "".to_string(),
payer: Payer { openid: "".to_string() },
amount: None
}
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WechatRefundNotifyResponseV3 {
pub raw_data: Option<OriginNotifyResponse>,
pub result: Option<DecryptRefundNotifyResult>,
}
impl WechatRefundNotifyResponseV3 {
pub fn decrypt_result(&self) -> DecryptRefundNotifyResult {
if let Some(res) = self.result.to_owned() {
res
} else {
DecryptRefundNotifyResult {
mchid: "".to_string(),
out_trade_no: "".to_string(),
transaction_id: "".to_string(),
out_refund_no: "".to_string(),
refund_id: "".to_string(),
success_time: "".to_string(),
amount: RefundAmount {
refund: 0,
total: 0,
payer_total: None,
payer_refund: None,
currency: None
},
refund_status: "".to_string(),
user_received_account: "".to_string()
}
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WxScanPayNotifyResponse {
pub openid: String,
pub is_subscribe: String,
pub product_id: String,
}
impl WxScanPayNotifyResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let openid = xmlutil::evaluate(&doc, "//xml/openid/text()").string();
let is_subscribe = xmlutil::evaluate(&doc, "//xml/is_subscribe/text()").string();
let product_id = xmlutil::evaluate(&doc, "//xml/product_id/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
let _sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let _err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
if result_code.eq("SUCCESS") {
Ok(WxScanPayNotifyResponse {
openid,
is_subscribe,
product_id
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: err_code_des})
}
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DecryptNotifyResult {
pub appid: String,
pub mchid: String,
pub out_trade_no: String,
pub transaction_id: String,
pub trade_type: String,
pub trade_state: String,
pub trade_state_desc: String,
pub bank_type: String,
pub attach: Option<String>,
pub success_time: String,
pub payer: Payer,
pub amount: Option<Amount>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DecryptRefundNotifyResult {
pub mchid: String,
pub out_trade_no: String,
pub transaction_id: String,
pub out_refund_no: String,
pub refund_id: String,
pub refund_status: String,
pub success_time: String,
pub user_received_account: String,
pub amount: RefundAmount,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OriginNotifyResponse {
pub id: String,
pub create_time: String,
pub event_type: String,
pub summary: String,
pub resource_type: String,
pub resource: EncryptV3,
}
#[allow(unused)]
impl WechatPayNotifyResponse {
pub fn parse_xml(xml: String) -> LabradorResult<Self> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let trade_type = xmlutil::evaluate(&doc, "//xml/trade_type/text()").string();
let mch_id = xmlutil::evaluate(&doc, "//xml/mch_id/text()").string();
let openid = xmlutil::evaluate(&doc, "//xml/openid/text()").string();
let nonce_str = xmlutil::evaluate(&doc, "//xml/nonce_str/text()").string();
let result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let bank_type = xmlutil::evaluate(&doc, "//xml/bank_type/text()").string();
let fee_type = xmlutil::evaluate(&doc, "//xml/fee_type/text()").string();
let sign = xmlutil::evaluate(&doc, "//xml/sign/text()").string();
let is_subscribe = xmlutil::evaluate(&doc, "//xml/is_subscribe/text()").string();
let out_trade_no = xmlutil::evaluate(&doc, "//xml/out_trade_no/text()").string();
let time_end = xmlutil::evaluate(&doc, "//xml/time_end/text()").string();
let total_fee = xmlutil::evaluate(&doc, "//xml/total_fee/text()").string();
let cash_fee = xmlutil::evaluate(&doc, "//xml/cash_fee/text()").string();
let coupon_fee = xmlutil::evaluate(&doc, "//xml/coupon_fee/text()").string();
let coupon_count = xmlutil::evaluate(&doc, "//xml/coupon_count/text()").string();
let coupon_id = xmlutil::evaluate(&doc, "//xml/coupon_id/text()").string();
let coupon_type = xmlutil::evaluate(&doc, "//xml/coupon_type/text()").string();
let transaction_id = xmlutil::evaluate(&doc, "//xml/transaction_id/text()").string();
let attach = xmlutil::evaluate(&doc, "//xml/attach/text()").string();
let err_code = xmlutil::evaluate(&doc, "//xml/err_code/text()").string();
let err_code_des = xmlutil::evaluate(&doc, "//xml/err_code_des/text()").string();
Ok(WechatPayNotifyResponse {
appid: appid.into(),
trade_type,
bank_type: bank_type.into(),
fee_type: fee_type.into(),
is_subscribe: is_subscribe.into(),
nonce_str: nonce_str.into(),
mch_id,
openid,
out_trade_no,
return_code,
sign,
err_code: err_code.into(),
err_code_des: err_code_des.into(),
time_end,
total_fee,
return_msg,
coupon_fee: coupon_fee.into(),
coupon_count: coupon_count.into(),
coupon_type: coupon_type.into(),
coupon_id: coupon_id.into(),
transaction_id,
attach: attach.into(),
result_code,
cash_fee,
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct WechatRefundNotifyResponse {
pub appid: Option<String>,
pub nonce_str: Option<String>,
pub mch_id: String,
pub req_info: String,
pub return_code: String,
pub return_msg: Option<String>,
}
#[derive(Debug, Serialize, Deserialize,Clone)]
pub struct WechatDecryptRefundNotifyResponse {
pub out_refund_no: String,
pub out_trade_no: String,
pub refund_account: String,
pub refund_fee: String,
pub refund_id: String,
pub refund_recv_accout: String,
pub refund_request_source: String,
pub refund_status: String,
pub settlement_refund_fee: String,
pub settlement_total_fee: String,
pub success_time: String,
pub total_fee: String,
pub transaction_id: String,
}
#[allow(unused)]
impl WechatRefundNotifyResponse {
pub fn parse_xml(xml: String, appkey: &str) -> LabradorResult<WechatDecryptRefundNotifyResponse> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let _appid = xmlutil::evaluate(&doc, "//xml/appid/text()").string();
let _result_code = xmlutil::evaluate(&doc, "//xml/result_code/text()").string();
let _return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
let req_info = xmlutil::evaluate(&doc, "//xml/req_info/text()").string();
let _refund_msg = WechatCrypto::decrypt_data_refund(appkey,req_info.as_str())?;
let refund_package = xmlutil::parse(_refund_msg.to_owned());
let refund_doc = refund_package.as_document();
let out_refund_no = xmlutil::evaluate(&refund_doc, "//root/out_refund_no/text()").string();
let out_trade_no = xmlutil::evaluate(&refund_doc, "//root/out_trade_no/text()").string();
let refund_account = xmlutil::evaluate(&refund_doc, "//root/refund_account/text()").string();
let refund_fee = xmlutil::evaluate(&refund_doc, "//root/refund_fee/text()").string();
let refund_id = xmlutil::evaluate(&refund_doc, "//root/refund_id/text()").string();
let refund_recv_accout = xmlutil::evaluate(&refund_doc, "//root/refund_recv_accout/text()").string();
let refund_request_source = xmlutil::evaluate(&refund_doc, "//root/refund_request_source/text()").string();
let refund_status = xmlutil::evaluate(&refund_doc, "//root/refund_status/text()").string();
let settlement_refund_fee = xmlutil::evaluate(&refund_doc, "//root/settlement_refund_fee/text()").string();
let settlement_total_fee = xmlutil::evaluate(&refund_doc, "//root/settlement_total_fee/text()").string();
let success_time = xmlutil::evaluate(&refund_doc, "//root/success_time/text()").string();
let total_fee = xmlutil::evaluate(&refund_doc, "//root/total_fee/text()").string();
let transaction_id = xmlutil::evaluate(&refund_doc, "//root/transaction_id/text()").string();
Ok(WechatDecryptRefundNotifyResponse {
out_refund_no,
out_trade_no,
refund_account,
refund_fee,
refund_id,
refund_recv_accout,
refund_request_source,
refund_status,
settlement_refund_fee,
settlement_total_fee,
success_time,
total_fee,
transaction_id,
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}
#[derive(Debug, Serialize, Deserialize,Clone)]
pub struct WxPayShortUrlResponse {
pub short_url: String,
}
#[allow(unused)]
impl WxPayShortUrlResponse {
pub fn parse_xml(xml: String) -> LabradorResult<WxPayShortUrlResponse> {
let package = xmlutil::parse(xml.to_owned());
let doc = package.as_document();
let return_code = xmlutil::evaluate(&doc, "//xml/return_code/text()").string();
let return_msg = xmlutil::evaluate(&doc, "//xml/return_msg/text()").string();
if return_code.eq(&"SUCCESS") {
let short_url = xmlutil::evaluate(&doc, "//xml/short_url/text()").string();
Ok(WxPayShortUrlResponse {
short_url,
})
} else {
Err(LabraError::ClientError{ errcode: "-1".to_string(), errmsg: return_msg})
}
}
}