1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3use crate::{core::request::Request, model::{Amount, Detail, Payer, SceneInfo, SettleInfo, SignData}, RPayResult};
4use super::config::WechatV3PayConfig;
5
6#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
7#[builder(pattern = "mutable")]
8pub struct JsApiPay {
9 #[serde(rename = "appid")]
11 #[builder(default="String::new()",setter(into))]
12 pub app_id: String,
13 #[serde(rename = "mchid")]
15 #[builder(default="String::new()",setter(into))]
16 pub mch_id: String,
17 #[builder(setter(into))]
19 pub description: String,
20 #[builder(setter(into))]
22 pub out_trade_no: String,
23 #[builder(default,setter(strip_option))]
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub time_expire: Option<String>,
27 #[builder(default,setter(strip_option))]
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub attach: Option<String>,
31 #[builder(default="String::new()",setter(into))]
33 pub notify_url: String,
34 #[builder(default,setter(strip_option))]
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub goods_tag: Option<String>,
38 #[builder(default = "Some(false)" , setter(strip_option))]
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub support_fapiao: Option<bool>,
42 pub amount: Amount,
44 pub payer: Payer,
46 #[builder(default, setter(strip_option))]
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub detail: Option<Detail>,
50 #[builder(default,setter(strip_option))]
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub scene_info: Option<SceneInfo>,
54 #[builder(default, setter(strip_option))]
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub settle_info: Option<SettleInfo>,
58}
59
60impl JsApiPay {
62 pub async fn pay(&mut self, wechat_sdk: WechatV3PayConfig) -> RPayResult<JsapiResponse> {
63 self.app_id = wechat_sdk.app_id.clone();
64 self.mch_id = wechat_sdk.mch_id.clone();
65 self.notify_url = wechat_sdk.notify_url.clone().unwrap_or_default();
66 let json_body = serde_json::to_string(self).unwrap();
67 Request::build_pay_request::<JsapiResponse>(wechat_sdk,crate::common::HttpMethod::POST, "/v3/pay/transactions/jsapi", json_body).await
68 }
69}
70
71#[derive(Debug, Deserialize, Serialize)]
72pub struct JsapiResponse {
73 pub code: Option<String>,
74 pub message: Option<String>,
75 pub prepay_id: Option<String>,
77 pub sign_data: Option<SignData>,
79}