1use serde::de::DeserializeOwned;
2use serde::{Deserialize, Serialize};
3
4pub trait ResponseTrait: DeserializeOwned {}
5
6#[derive(Debug, Deserialize)]
7pub struct NativeResponse {
8 pub code: Option<String>,
9 pub message: Option<String>,
10 pub code_url: Option<String>,
12}
13
14impl ResponseTrait for NativeResponse {}
15
16#[derive(Debug, Deserialize)]
17pub struct JsapiResponse {
18 pub code: Option<String>,
19 pub message: Option<String>,
20 pub prepay_id: Option<String>,
22 pub sign_data: Option<SignData>,
24}
25
26#[derive(Debug, Serialize, Deserialize)]
27pub struct SignData {
28 pub app_id: String,
29 pub sign_type: String,
30 pub package: String,
31 pub nonce_str: String,
32 pub timestamp: String,
33 pub pay_sign: String,
34}
35
36impl ResponseTrait for JsapiResponse {}
37
38#[derive(Debug, Deserialize)]
39pub struct AppResponse {
40 pub code: Option<String>,
41 pub message: Option<String>,
42 pub prepay_id: Option<String>,
44 pub sign_data: Option<SignData>,
46}
47
48impl ResponseTrait for AppResponse {}
49
50#[derive(Debug, Deserialize)]
51pub struct MicroResponse {
52 pub code: Option<String>,
53 pub message: Option<String>,
54 pub prepay_id: Option<String>,
56 pub sign_data: Option<SignData>,
58}
59
60impl ResponseTrait for MicroResponse {}
61
62#[derive(Debug, Deserialize)]
63pub struct H5Response {
64 pub code: Option<String>,
65 pub message: Option<String>,
66 pub h5_url: Option<String>,
69}
70
71impl ResponseTrait for H5Response {}
72
73#[derive(Debug, Clone, Deserialize)]
74pub struct EncryptCertificate {
75 pub algorithm: String,
76 pub nonce: String,
77 pub associated_data: String,
78 pub ciphertext: String,
79}
80
81#[derive(Debug, Clone, Deserialize)]
82pub struct Certificate {
83 pub serial_no: String,
84 pub effective_time: String,
85 pub expire_time: String,
86 pub encrypt_certificate: EncryptCertificate,
87}
88
89#[derive(Debug, Deserialize)]
90pub struct CertificateResponse {
91 pub data: Option<Vec<Certificate>>,
92}
93
94impl ResponseTrait for CertificateResponse {}
95
96#[derive(Deserialize, Debug)]
97#[serde(untagged, bound = "T: ResponseTrait + DeserializeOwned")]
98pub enum WeChatResponse<T>
99where
100 T: ResponseTrait + DeserializeOwned,
101{
102 Ok(T),
103 Err(ErrorResponse),
104}
105
106impl<T> ResponseTrait for WeChatResponse<T> where T: ResponseTrait + DeserializeOwned {}
107
108impl<T> WeChatResponse<T>
109where
110 T: ResponseTrait + DeserializeOwned,
111{
112 pub fn is_success(&self) -> bool {
113 matches!(self, WeChatResponse::Ok(_))
114 }
115
116 pub fn ok(&self) -> Option<&T> {
117 if let WeChatResponse::Ok(response) = self {
118 Some(response)
119 } else {
120 None
121 }
122 }
123
124 pub fn err(&self) -> Option<&ErrorResponse> {
125 if let WeChatResponse::Err(error_response) = self {
126 Some(error_response)
127 } else {
128 None
129 }
130 }
131}
132
133#[derive(Deserialize, Debug)]
134pub struct ErrorResponse {
135 pub code: Option<String>,
137 pub message: Option<String>,
139}
140
141#[derive(Debug, Deserialize)]
142pub struct RefundsResponse {
143 pub refund_id: String,
145 pub out_refund_no: String,
147 pub transaction_id: String,
149 pub out_trade_no: String,
151 pub channel: String,
158 pub user_received_account: String,
169 pub success_time: Option<String>,
174 pub create_time: String,
179 pub status: String,
186 pub funds_account: String,
194 pub amount: RefundsAmountResponse,
196 pub promotion_detail: Option<Vec<RefundsPromotionDetailResponse>>,
198}
199
200impl ResponseTrait for RefundsResponse {}
201
202#[derive(Debug, Deserialize)]
203pub struct RefundsAmountResponse {
204 pub total: i32,
206 pub refund: i32,
208 pub from: Option<Vec<RefundsFromResponse>>,
210 pub payer_total: i32,
212 pub payer_refund: i32,
216 pub settlement_refund: i32,
218 pub settlement_total: i32,
220 pub discount_refund: i32,
222 pub currency: String,
224 pub refund_fee: Option<i32>,
226}
227
228#[derive(Debug, Deserialize)]
229pub struct RefundsFromResponse {
230 pub account: String,
235 pub amount: i32,
237}
238
239#[derive(Debug, Deserialize)]
240pub struct RefundsPromotionDetailResponse {
241 pub promotion_id: String,
243 pub scope: String,
247 pub r#type: String,
251 pub amount: i32,
253 pub refund_amount: i32,
255 pub goods_detail: Option<Vec<RefundsGoodsDetailResponse>>,
257}
258
259#[derive(Debug, Deserialize)]
260pub struct RefundsGoodsDetailResponse {
261 pub merchant_goods_id: Option<String>,
263 pub wechatpay_goods_id: Option<String>,
265 pub goods_name: Option<String>,
267 pub unit_price: i32,
269 pub refund_amount: i32,
271 pub refund_quantity: i32,
273}