rpay/wechat/pay/
jsapi.rs

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    /// 【公众号ID】 公众号ID (必填:不能长度大于32个字)
10    #[serde(rename = "appid")]
11    #[builder(default="String::new()",setter(into))]
12    pub app_id: String,
13    /// 【直连商户号】 直连商户号(必填:不能长度大于32个字)
14    #[serde(rename = "mchid")]
15    #[builder(default="String::new()",setter(into))]
16    pub mch_id: String,
17    /// 商品描述 (必填:不能长度大于127个字)
18    #[builder(setter(into))]
19    pub description: String,
20    /// 商户系统内部订单号,(必填:不能长度大于32个字)只能是数字、大小写字母_-*且在同一个商户号下唯一。
21    #[builder(setter(into))]
22    pub out_trade_no: String,
23    ///【交易结束时间】(选填:不能长度大于64个字) 订单失效时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日13点29分35秒。
24    #[builder(default,setter(strip_option))]
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub time_expire: Option<String>,
27    /// 【附加数据】(选填:不能长度大于128个字) 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用,实际情况下只有支付完成状态才会返回该字段。
28    #[builder(default,setter(strip_option))]
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub attach: Option<String>,
31    /// 【通知地址】 (选填:不能长度大于255个字) 异步接收微信支付结果通知的回调地址,通知URL必须为外网可访问的URL,不能携带参数。 公网域名必须为HTTPS,如果是走专线接入,使用专线NAT IP或者私有回调域名可使用HTTP
32    #[builder(default="String::new()",setter(into))]
33    pub notify_url: String,
34    /// 【订单优惠标记】 选填(32) 订单优惠标记
35    #[builder(default,setter(strip_option))]
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub goods_tag: Option<String>,
38    /// 【电子发票入口开放标识】选填 boolean 传入true时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效。
39    #[builder(default = "Some(false)" , setter(strip_option))]
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub support_fapiao: Option<bool>,
42    ///必填 Amount 【订单金额】 订单金额信息
43    pub amount: Amount,
44    /// 必填 Payer【支付者】 支付者信息
45    pub payer: Payer,
46    /// 选填 Detail 【优惠功能】 优惠功能
47    #[builder(default, setter(strip_option))]
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub detail: Option<Detail>,
50    /// 选填 SceneInfo【场景信息】支付场景描述
51    #[builder(default,setter(strip_option))]
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub scene_info: Option<SceneInfo>,
54    /// 选填 SettleInfo【结算信息】 结算信息
55    #[builder(default, setter(strip_option))]
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub settle_info: Option<SettleInfo>,
58}
59
60/// 创建请求
61impl 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    ///【预支付交易会话标识】 预支付交易会话标识。用于后续接口调用中使用,该值有效期为2小时
76    pub prepay_id: Option<String>,
77    ///【签名数据】
78    pub sign_data: Option<SignData>,
79}