Add webhook
This commit is contained in:
parent
5801dbea2d
commit
ab1661100b
388
Cargo.lock
generated
388
Cargo.lock
generated
@ -265,7 +265,7 @@ version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
@ -277,7 +277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
@ -360,6 +360,42 @@ version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stripe"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65bb25e3145c6216eafb3eca6f8cd6e016f43c9d4416d0af7984de46acf4f288"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"hmac",
|
||||
"http-types",
|
||||
"hyper 0.14.26",
|
||||
"hyper-tls 0.5.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_qs 0.10.1",
|
||||
"sha2",
|
||||
"smart-default",
|
||||
"smol_str",
|
||||
"thiserror",
|
||||
"tokio 1.28.0",
|
||||
"uuid 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.68"
|
||||
@ -799,6 +835,15 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6d59c71e7dc3af60f0af9db32364d96a16e9310f3f5db2b55ed642162dd35"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.1.0"
|
||||
@ -1389,18 +1434,6 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-as-inner"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-ordinalize"
|
||||
version = "3.1.12"
|
||||
@ -1734,6 +1767,21 @@ version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
"parking",
|
||||
"pin-project-lite 0.2.9",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
@ -1794,6 +1842,17 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.9"
|
||||
@ -2076,17 +2135,6 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"match_cfg",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
@ -2119,6 +2167,27 @@ dependencies = [
|
||||
"pin-project-lite 0.2.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-types"
|
||||
version = "2.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel",
|
||||
"base64 0.13.1",
|
||||
"futures-lite",
|
||||
"http",
|
||||
"infer",
|
||||
"pin-project-lite 0.2.9",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_qs 0.8.5",
|
||||
"serde_urlencoded",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
@ -2279,6 +2348,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac"
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.29.0"
|
||||
@ -2382,18 +2457,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipconfig"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
|
||||
dependencies = [
|
||||
"socket2 0.3.19",
|
||||
"widestring",
|
||||
"winapi 0.3.9",
|
||||
"winreg 0.6.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.7.2"
|
||||
@ -2691,15 +2754,6 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru-cache"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzma-sys"
|
||||
version = "0.1.20"
|
||||
@ -2730,12 +2784,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "match_cfg"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
@ -2899,7 +2947,7 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3137,6 +3185,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
@ -3232,6 +3286,7 @@ dependencies = [
|
||||
name = "payment_adapter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"config",
|
||||
@ -3277,20 +3332,6 @@ dependencies = [
|
||||
"wasmtime-provider",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "payup"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d91028a90d25a925901ce59668da6bb074cb374d80f84a648a5b9a60f8b598"
|
||||
dependencies = [
|
||||
"reqwest 0.11.17",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tokio 1.28.0",
|
||||
"trust-dns-resolver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
@ -3478,12 +3519,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
@ -3526,7 +3561,7 @@ dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_hc 0.1.0",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
@ -3535,6 +3570,19 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -3556,6 +3604,16 @@ dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
@ -3581,13 +3639,22 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3599,6 +3666,15 @@ dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
@ -3716,7 +3792,7 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
"redox_syscall 0.2.16",
|
||||
"thiserror",
|
||||
]
|
||||
@ -3829,7 +3905,6 @@ dependencies = [
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
@ -3847,16 +3922,6 @@ dependencies = [
|
||||
"winreg 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resolv-conf"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
||||
dependencies = [
|
||||
"hostname",
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
@ -4178,7 +4243,7 @@ checksum = "9c0e296ea0569d20467e9a1df3cb6ed66ce3b791a7eaf1e1110ae231f75e2b46"
|
||||
dependencies = [
|
||||
"enclose",
|
||||
"futures",
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
"gloo-file",
|
||||
"gloo-timers",
|
||||
"gloo-utils",
|
||||
@ -4260,6 +4325,37 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_path_to_error"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_qs"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_qs"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.1"
|
||||
@ -4389,6 +4485,26 @@ version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "smart-default"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.19"
|
||||
@ -4603,11 +4719,12 @@ dependencies = [
|
||||
name = "stripe_adapter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"async-stripe",
|
||||
"async-trait",
|
||||
"derive_more",
|
||||
"fulfillment_adapter",
|
||||
"payment_adapter",
|
||||
"payup",
|
||||
"serde",
|
||||
"tokio 1.28.0",
|
||||
"tracing",
|
||||
@ -5245,67 +5362,6 @@ dependencies = [
|
||||
"inventory",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trust-dns-native-tls"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3061a6b3a19c97ffddc52359221b4b854255750bf2c48b7e52db50dd81dfa13"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"native-tls",
|
||||
"tokio 1.28.0",
|
||||
"tokio-native-tls",
|
||||
"trust-dns-proto",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trust-dns-proto"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"cfg-if 1.0.0",
|
||||
"data-encoding",
|
||||
"enum-as-inner",
|
||||
"futures-channel",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"idna 0.2.3",
|
||||
"ipnet",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tinyvec",
|
||||
"tokio 1.28.0",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trust-dns-resolver"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecae383baad9995efaa34ce8e57d12c3f305e545887472a492b838f4b5cfb77a"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"futures-util",
|
||||
"ipconfig",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lru-cache",
|
||||
"parking_lot 0.11.2",
|
||||
"resolv-conf",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tokio 1.28.0",
|
||||
"tokio-native-tls",
|
||||
"trust-dns-native-tls",
|
||||
"trust-dns-proto",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
@ -5420,6 +5476,7 @@ dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna 0.3.0",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5428,7 +5485,7 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -5439,7 +5496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"getrandom",
|
||||
"getrandom 0.2.9",
|
||||
"md-5",
|
||||
"serde",
|
||||
"sha1_smol",
|
||||
@ -5484,6 +5541,12 @@ version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
@ -5529,6 +5592,12 @@ dependencies = [
|
||||
"wapc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
@ -6008,12 +6077,6 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
|
||||
|
||||
[[package]]
|
||||
name = "wiggle"
|
||||
version = "3.0.1"
|
||||
@ -6307,15 +6370,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.7.0"
|
||||
|
@ -193,6 +193,12 @@ pub struct CurrencyCode([char; 3]);
|
||||
|
||||
impl Into<String> for CurrencyCode {
|
||||
fn into(self) -> String {
|
||||
self.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for CurrencyCode {
|
||||
fn to_string(&self) -> String {
|
||||
let mut s = String::with_capacity(3);
|
||||
for c in self.0 {
|
||||
s.push(c);
|
||||
|
@ -15,3 +15,4 @@ async-trait = { version = "0.1.68" }
|
||||
chrono = { version = "0.4.24" }
|
||||
toml = { version = "0.7.3" }
|
||||
traitcast = { version = "0.5.0" }
|
||||
actix-web = { version = "4.3.1" }
|
||||
|
@ -8,13 +8,6 @@ pub use model::v3::*;
|
||||
pub use uuid;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
||||
#[repr(C)]
|
||||
pub enum Status {
|
||||
Success = 0,
|
||||
Failure = 1,
|
||||
}
|
||||
|
||||
pub struct AnyData(pub Vec<u8>);
|
||||
|
||||
pub struct PaymentProcessorError {
|
||||
@ -48,7 +41,7 @@ pub struct PaymentProcessorContext {
|
||||
pub resource_id: String,
|
||||
pub customer: Option<Customer>,
|
||||
pub context: PaymentProcessCtx,
|
||||
pub payment_session_data: Box<dyn PaymentSessionData>,
|
||||
pub payment_session_data: Option<Box<dyn PaymentSessionData>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
@ -121,12 +114,24 @@ pub struct Refunded {}
|
||||
pub enum PError {
|
||||
#[error("Payment gate request failed")]
|
||||
HttpError,
|
||||
#[error("Operation requires Charge id")]
|
||||
NoChargeId,
|
||||
#[error("Operation requires payment intent id")]
|
||||
NoPaymentIntentId,
|
||||
#[error("Operation requires customer to be fulfill")]
|
||||
RequiresCustomer,
|
||||
#[error("Operation requires customer payment gate id to be fulfill")]
|
||||
RequiresCustomerExtId,
|
||||
#[error("There's no charge with id {0:?}")]
|
||||
ChargeNotExists(String),
|
||||
#[error("Failed capture charge with id {0:?}")]
|
||||
FailedCapture(String),
|
||||
#[error("Failed to capture payment intent with id {0:?}")]
|
||||
CaptureFailed(String),
|
||||
#[error("Failed to cancel payment intent with id {0:?}")]
|
||||
CancelFailed(String),
|
||||
#[error("Failed to update payment intent with id {0:?}")]
|
||||
UpdateFailed(String),
|
||||
#[error("Failed to create refund for payment intent with id {0:?}")]
|
||||
RefundFailed(String),
|
||||
#[error("Payment init failed")]
|
||||
InitializeFailed,
|
||||
#[error("Invalid charge for given payment adapter")]
|
||||
InvalidType,
|
||||
}
|
||||
@ -145,12 +150,14 @@ impl Config {
|
||||
pub trait PaymentAdapter {
|
||||
async fn new(config: Config) -> Self;
|
||||
|
||||
fn identifier(&self) -> &'static str;
|
||||
|
||||
/**
|
||||
* Initiate a payment session with the external provider
|
||||
*/
|
||||
async fn initialize_payment(
|
||||
&mut self,
|
||||
ctx: PaymentProcessorContext,
|
||||
ctx: &mut PaymentProcessorContext,
|
||||
) -> PResult<PaymentProcessorSessionResponse>;
|
||||
|
||||
/**
|
||||
@ -158,7 +165,7 @@ pub trait PaymentAdapter {
|
||||
*/
|
||||
async fn update_payment(
|
||||
&mut self,
|
||||
ctx: PaymentProcessorContext,
|
||||
ctx: &mut PaymentProcessorContext,
|
||||
) -> PResult<Option<PaymentProcessorSessionResponse>>;
|
||||
|
||||
/**
|
||||
@ -201,7 +208,7 @@ pub trait PaymentAdapter {
|
||||
async fn retrieve_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()>;
|
||||
) -> PResult<Box<dyn PaymentSessionData>>;
|
||||
|
||||
/**
|
||||
* Cancel an existing session
|
||||
@ -231,3 +238,7 @@ pub fn session_mut_ref<T: PaymentSessionData + Any>(
|
||||
) -> Option<&mut T> {
|
||||
<dyn Any>::downcast_mut(session)
|
||||
}
|
||||
|
||||
pub trait Plugin {
|
||||
fn mount(&self, config: &mut actix_web::web::ServiceConfig);
|
||||
}
|
||||
|
@ -13,8 +13,9 @@ rustflags = ["-C", "prefer-dynamic", "-C", "rpath"]
|
||||
payment_adapter = { path = "../payment_adapter" }
|
||||
fulfillment_adapter = { path = "../fulfillment_adapter" }
|
||||
tokio = { version = "1.27.0" }
|
||||
payup = { version = "*", features = [] }
|
||||
tracing = { version = "0.1.37" }
|
||||
async-trait = { version = "0.1.68" }
|
||||
serde = { version = "1.0.162", features = ['derive'] }
|
||||
derive_more = { version = "0.99.17" }
|
||||
async-stripe = { version = "0.21.0", features = ['tokio', 'async', 'runtime-tokio-hyper'] }
|
||||
actix-web = { version = "4.3.1" }
|
||||
|
@ -1,12 +1,15 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ops::DerefMut;
|
||||
use std::str::FromStr;
|
||||
|
||||
use derive_more::DerefMut;
|
||||
use actix_web::HttpResponse;
|
||||
use fulfillment_adapter::*;
|
||||
use payment_adapter::*;
|
||||
use payup::stripe;
|
||||
use tracing::warn;
|
||||
|
||||
mod przelewy_24;
|
||||
mod routes;
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub enum CaptureMethod {
|
||||
@ -14,7 +17,7 @@ pub enum CaptureMethod {
|
||||
Manual,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[derive(Debug, Copy, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub enum SetupFutureUsage {
|
||||
OnSession,
|
||||
OffSession,
|
||||
@ -33,199 +36,35 @@ pub struct StripeIntent {
|
||||
pub payment_method_types: &'static [&'static str],
|
||||
}
|
||||
|
||||
pub struct StripeAdapter {
|
||||
stripe: stripe::Auth,
|
||||
config: StripeConfig,
|
||||
}
|
||||
|
||||
async fn payment_status(stripe: stripe::Auth, ext_id: String) -> FResult<PaymentSessionStatus> {
|
||||
let charge: stripe::Charge = stripe::Charge::async_get(stripe, ext_id)
|
||||
async fn payment_status(
|
||||
client: &::stripe::Client,
|
||||
ext_id: String,
|
||||
) -> FResult<PaymentSessionStatus> {
|
||||
let id = ::stripe::PaymentIntentId::from_str(&ext_id).map_err(|e| {
|
||||
warn!("{e}");
|
||||
FError::HttpError
|
||||
})?;
|
||||
let intent = ::stripe::PaymentIntent::retrieve(client, &id, &[])
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::warn!("{e}");
|
||||
warn!("{e}");
|
||||
FError::HttpError
|
||||
})?;
|
||||
Ok(match charge.status.as_deref() {
|
||||
Some("requires_payment_method" | "requires_confirmation" | "processing") => {
|
||||
PaymentSessionStatus::Pending
|
||||
}
|
||||
Some("requires_action") => PaymentSessionStatus::RequiresMore,
|
||||
Some("canceled") => PaymentSessionStatus::Canceled,
|
||||
Some("requires_capture" | "succeeded") => PaymentSessionStatus::Authorized,
|
||||
_ => PaymentSessionStatus::Pending,
|
||||
Ok(match intent.status {
|
||||
::stripe::PaymentIntentStatus::RequiresPaymentMethod
|
||||
| ::stripe::PaymentIntentStatus::RequiresConfirmation
|
||||
| ::stripe::PaymentIntentStatus::Processing => PaymentSessionStatus::Pending,
|
||||
::stripe::PaymentIntentStatus::RequiresAction => PaymentSessionStatus::RequiresMore,
|
||||
::stripe::PaymentIntentStatus::Canceled => PaymentSessionStatus::Canceled,
|
||||
::stripe::PaymentIntentStatus::RequiresCapture
|
||||
| ::stripe::PaymentIntentStatus::Succeeded => PaymentSessionStatus::Authorized,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct StripePrzelewy24Config {
|
||||
pub api_key: String,
|
||||
pub client: String,
|
||||
pub webhook_secret: String,
|
||||
pub capture: Option<bool>,
|
||||
pub automatic_payment_methods: Option<bool>,
|
||||
pub payment_description: Option<String>,
|
||||
}
|
||||
|
||||
pub struct StripePrzelewy24 {
|
||||
stripe: stripe::Auth,
|
||||
config: StripePrzelewy24Config,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl PaymentAdapter for StripePrzelewy24 {
|
||||
async fn new(config: Config) -> Self {
|
||||
let config: StripePrzelewy24Config =
|
||||
config.config().expect("Malformed Stripe Przelewy24 config");
|
||||
let stripe = stripe::Auth::new(config.client.clone(), config.api_key.clone());
|
||||
Self { config, stripe }
|
||||
}
|
||||
|
||||
async fn initialize_payment(
|
||||
&mut self,
|
||||
ctx: PaymentProcessorContext,
|
||||
) -> PResult<PaymentProcessorSessionResponse> {
|
||||
let PaymentProcessorContext {
|
||||
billing_address: _,
|
||||
email,
|
||||
currency_code,
|
||||
amount,
|
||||
resource_id: _,
|
||||
customer,
|
||||
context,
|
||||
payment_session_data,
|
||||
} = ctx;
|
||||
let desc = context
|
||||
.0
|
||||
.get("payment_description")
|
||||
.and_then(|v| String::from_utf8(v.0.clone()).ok())
|
||||
.or_else(|| self.config.payment_description.clone());
|
||||
|
||||
let change: stripe::Charge = stripe::Charge {
|
||||
amount: Some(amount.0.to_string()),
|
||||
captured: self.config.capture.clone(),
|
||||
currency: Some(currency_code.into()),
|
||||
description: desc,
|
||||
customer: customer.as_ref().map(|c| c.id.0.to_string()),
|
||||
receipt_email: Some(email.0),
|
||||
..stripe::Charge::new()
|
||||
}
|
||||
.async_post(self.stripe.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let update_requests = match customer.as_ref() {
|
||||
Some(c) if !c.has_stripe_id() => Some(UpdateRequests {
|
||||
customer_metadata: Some(CustomerMetadata(HashMap::from([(
|
||||
"id".to_string(),
|
||||
AnyData(change.customer.clone().unwrap_or_default().into_bytes()),
|
||||
)]))),
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Ok(PaymentProcessorSessionResponse {
|
||||
update_requests,
|
||||
session_data: Box::new(Charge(change)),
|
||||
})
|
||||
}
|
||||
|
||||
async fn update_payment(
|
||||
&mut self,
|
||||
ctx: PaymentProcessorContext,
|
||||
) -> PResult<Option<PaymentProcessorSessionResponse>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn refund_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
refund_amount: Amount,
|
||||
) -> PResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn authorize_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
data: PaymentProcessCtx,
|
||||
) -> PResult<(PaymentSessionStatus, ())> {
|
||||
self.payment_status(payment_session_data)
|
||||
.await
|
||||
.map(|status| (status, ()))
|
||||
}
|
||||
|
||||
async fn capture_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
let Some(session) = session_mut_ref::<Charge>(payment_session_data) else {
|
||||
return Err(PError::InvalidType);
|
||||
};
|
||||
let id = session.id().ok_or_else(|| PError::NoChargeId)?;
|
||||
let charge = stripe::Charge::async_get(self.stripe.clone(), id.clone())
|
||||
.await
|
||||
.map_err(|_| PError::ChargeNotExists(id.clone()))?;
|
||||
let change = charge
|
||||
.async_capture(self.stripe.clone())
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::warn!("{e}");
|
||||
PError::FailedCapture(id)
|
||||
})?;
|
||||
session.0 = change;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn retrieve_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn cancel_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn payment_status(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<PaymentSessionStatus> {
|
||||
payment_status(
|
||||
self.stripe.clone(),
|
||||
payment_session_data
|
||||
.id()
|
||||
.ok_or_else(|| PError::NoChargeId)?,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| PError::HttpError)
|
||||
}
|
||||
}
|
||||
|
||||
impl StripePrzelewy24 {
|
||||
pub fn payment_intent_options() -> StripeIntent {
|
||||
StripeIntent {
|
||||
capture_method: CaptureMethod::Automatic,
|
||||
setup_future_usage: SetupFutureUsage::OnSession,
|
||||
payment_method_types: &["p24"],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait StripeCustomerMetadata {
|
||||
fn has_stripe_id(&self) -> bool;
|
||||
|
||||
fn stripe_id(&self) -> Option<String>;
|
||||
fn stripe_id(&self) -> Option<&str>;
|
||||
}
|
||||
|
||||
impl StripeCustomerMetadata for Customer {
|
||||
@ -235,19 +74,27 @@ impl StripeCustomerMetadata for Customer {
|
||||
.map_or_else(|| false, |h| h.contains_key("stripe_id"))
|
||||
}
|
||||
|
||||
fn stripe_id(&self) -> Option<String> {
|
||||
fn stripe_id(&self) -> Option<&str> {
|
||||
self.metadata
|
||||
.as_ref()?
|
||||
.get("stripe_id")
|
||||
.and_then(|v| String::from_utf8(v.clone()).ok())
|
||||
.and_then(|v| std::str::from_utf8(v).ok())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, derive_more::Deref, derive_more::DerefMut)]
|
||||
struct Charge(stripe::Charge);
|
||||
struct Intent(::stripe::PaymentIntent);
|
||||
|
||||
impl PaymentSessionData for Charge {
|
||||
impl PaymentSessionData for Intent {
|
||||
fn id(&self) -> Option<String> {
|
||||
self.0.id.clone()
|
||||
Some(self.id.as_str().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StripePlugin {}
|
||||
|
||||
impl Plugin for StripePlugin {
|
||||
fn mount(&self, config: &mut actix_web::web::ServiceConfig) {
|
||||
config.service(routes::stripe_hooks);
|
||||
}
|
||||
}
|
||||
|
330
crates/stripe_adapter/src/przelewy_24.rs
Normal file
330
crates/stripe_adapter/src/przelewy_24.rs
Normal file
@ -0,0 +1,330 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use payment_adapter::{
|
||||
session_mut_ref, session_ref, Amount, AnyData, Config, CustomerMetadata, PError, PResult,
|
||||
PaymentAdapter, PaymentProcessCtx, PaymentProcessorContext, PaymentProcessorSessionResponse,
|
||||
PaymentSessionData, PaymentSessionStatus, UpdateRequests,
|
||||
};
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{Intent, SetupFutureUsage, StripeCustomerMetadata};
|
||||
|
||||
pub struct StripePrzelewy24 {
|
||||
config: StripePrzelewy24Config,
|
||||
client: ::stripe::Client,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl PaymentAdapter for StripePrzelewy24 {
|
||||
async fn new(config: Config) -> Self {
|
||||
let config: StripePrzelewy24Config =
|
||||
config.config().expect("Malformed Stripe Przelewy24 config");
|
||||
let client = ::stripe::Client::new(config.api_key.as_str());
|
||||
Self { config, client }
|
||||
}
|
||||
|
||||
fn identifier(&self) -> &'static str {
|
||||
"stripe-przelewy24"
|
||||
}
|
||||
|
||||
async fn initialize_payment(
|
||||
&mut self,
|
||||
ctx: &mut PaymentProcessorContext,
|
||||
) -> PResult<PaymentProcessorSessionResponse> {
|
||||
let PaymentProcessorContext {
|
||||
billing_address: _,
|
||||
email,
|
||||
currency_code,
|
||||
amount,
|
||||
resource_id,
|
||||
customer,
|
||||
context,
|
||||
payment_session_data: _,
|
||||
} = ctx;
|
||||
|
||||
let desc = context
|
||||
.0
|
||||
.get("payment_description")
|
||||
.and_then(|v| String::from_utf8(v.0.clone()).ok())
|
||||
.or_else(|| self.config.payment_description.clone());
|
||||
|
||||
let intent = ::stripe::PaymentIntent::create(
|
||||
&self.client,
|
||||
::stripe::CreatePaymentIntent {
|
||||
amount: amount.0,
|
||||
application_fee_amount: None,
|
||||
automatic_payment_methods: self.config.automatic_payment_methods.clone().map(
|
||||
|enabled| ::stripe::CreatePaymentIntentAutomaticPaymentMethods { enabled },
|
||||
),
|
||||
capture_method: Some(::stripe::PaymentIntentCaptureMethod::Automatic),
|
||||
confirm: None,
|
||||
confirmation_method: None,
|
||||
currency: ::stripe::Currency::from_str(¤cy_code.to_string())
|
||||
.unwrap_or_else(|_| ::stripe::Currency::default()),
|
||||
customer: None,
|
||||
description: desc.as_deref(),
|
||||
error_on_requires_action: None,
|
||||
expand: &[],
|
||||
mandate: None,
|
||||
mandate_data: None,
|
||||
metadata: Some({
|
||||
let mut m = ::stripe::Metadata::with_capacity(1);
|
||||
m.insert("resource_id".into(), resource_id.clone());
|
||||
m
|
||||
}),
|
||||
off_session: None,
|
||||
on_behalf_of: None,
|
||||
payment_method: None,
|
||||
payment_method_data: None,
|
||||
payment_method_options: None,
|
||||
payment_method_types: Some(vec!["p24".into()]),
|
||||
radar_options: None,
|
||||
receipt_email: Some(email.0.as_str()),
|
||||
return_url: None,
|
||||
setup_future_usage: Some(::stripe::PaymentIntentSetupFutureUsage::OnSession),
|
||||
shipping: None,
|
||||
statement_descriptor: None,
|
||||
statement_descriptor_suffix: None,
|
||||
transfer_data: None,
|
||||
transfer_group: None,
|
||||
use_stripe_sdk: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Initialize payment failed: {e}");
|
||||
PError::InitializeFailed
|
||||
})?;
|
||||
|
||||
let update_requests = match customer.as_ref() {
|
||||
Some(c) if !c.has_stripe_id() => Some(UpdateRequests {
|
||||
customer_metadata: Some(CustomerMetadata(HashMap::from([(
|
||||
"id".to_string(),
|
||||
AnyData(
|
||||
intent
|
||||
.customer
|
||||
.clone()
|
||||
.map(|customer| customer.id())
|
||||
.unwrap_or_default()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
),
|
||||
)]))),
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Ok(PaymentProcessorSessionResponse {
|
||||
update_requests,
|
||||
session_data: Box::new(Intent(intent)),
|
||||
})
|
||||
}
|
||||
|
||||
async fn update_payment(
|
||||
&mut self,
|
||||
ctx: &mut PaymentProcessorContext,
|
||||
) -> PResult<Option<PaymentProcessorSessionResponse>> {
|
||||
let customer = ctx
|
||||
.customer
|
||||
.as_ref()
|
||||
.ok_or_else(|| PError::RequiresCustomer)?;
|
||||
let stripe_id = &customer
|
||||
.stripe_id()
|
||||
.ok_or_else(|| PError::RequiresCustomerExtId)?;
|
||||
|
||||
let session = ctx
|
||||
.payment_session_data
|
||||
.as_mut()
|
||||
.and_then(|session| session_mut_ref::<Intent>(session))
|
||||
.ok_or_else(|| PError::InvalidType)?;
|
||||
|
||||
let session_customer_id = session.customer.as_ref().map(|c| c.id());
|
||||
if session_customer_id.map(|c| c.as_str() == *stripe_id) == Some(false) {
|
||||
return self.initialize_payment(ctx).await.map(Some);
|
||||
} else if let Some(session) = &mut ctx.payment_session_data {
|
||||
let session =
|
||||
session_ref::<Intent>(session).ok_or_else(|| PError::NoPaymentIntentId)?;
|
||||
|
||||
if ctx.amount.0 == session.amount {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let intent = ::stripe::PaymentIntent::update(
|
||||
&self.client,
|
||||
&session.id,
|
||||
::stripe::UpdatePaymentIntent {
|
||||
amount: Some(ctx.amount.0.clone()),
|
||||
application_fee_amount: None,
|
||||
capture_method: None,
|
||||
currency: None,
|
||||
customer: None,
|
||||
description: None,
|
||||
expand: &[],
|
||||
metadata: None,
|
||||
payment_method: None,
|
||||
payment_method_data: None,
|
||||
payment_method_options: None,
|
||||
payment_method_types: None,
|
||||
receipt_email: None,
|
||||
setup_future_usage: None,
|
||||
shipping: None,
|
||||
statement_descriptor: None,
|
||||
statement_descriptor_suffix: None,
|
||||
transfer_data: None,
|
||||
transfer_group: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Failed to update payment intent: {e}");
|
||||
PError::UpdateFailed(session.id.as_str().to_string())
|
||||
})?;
|
||||
Ok(Some(PaymentProcessorSessionResponse {
|
||||
update_requests: None,
|
||||
session_data: Box::new(Intent(intent)),
|
||||
}))
|
||||
} else {
|
||||
Err(PError::NoPaymentIntentId)
|
||||
}
|
||||
}
|
||||
|
||||
async fn refund_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
refund_amount: Amount,
|
||||
) -> PResult<()> {
|
||||
let session = session_mut_ref::<Intent>(payment_session_data)
|
||||
.ok_or_else(|| PError::NoPaymentIntentId)?;
|
||||
|
||||
::stripe::Refund::create(
|
||||
&self.client,
|
||||
::stripe::CreateRefund {
|
||||
amount: Some(refund_amount.0),
|
||||
charge: None,
|
||||
currency: None,
|
||||
customer: None,
|
||||
expand: &[],
|
||||
instructions_email: None,
|
||||
metadata: None,
|
||||
origin: None,
|
||||
payment_intent: Some(session.id.clone()),
|
||||
reason: None,
|
||||
refund_application_fee: None,
|
||||
reverse_transfer: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Failed to create refund: {e}");
|
||||
PError::RefundFailed(session.id.as_str().to_string())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn authorize_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
_data: PaymentProcessCtx,
|
||||
) -> PResult<(PaymentSessionStatus, ())> {
|
||||
self.payment_status(payment_session_data)
|
||||
.await
|
||||
.map(|status| (status, ()))
|
||||
}
|
||||
|
||||
async fn capture_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
let Some(session) = session_mut_ref::<Intent>(payment_session_data) else {
|
||||
return Err(PError::InvalidType);
|
||||
};
|
||||
let id = session.0.id.as_str();
|
||||
|
||||
let intent = ::stripe::PaymentIntent::capture(
|
||||
&self.client,
|
||||
id,
|
||||
::stripe::CapturePaymentIntent {
|
||||
amount_to_capture: None,
|
||||
application_fee_amount: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("{e}");
|
||||
PError::CaptureFailed(id.to_owned())
|
||||
})?;
|
||||
session.0 = intent;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
self.cancel_payment(payment_session_data).await
|
||||
}
|
||||
|
||||
async fn retrieve_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<Box<dyn PaymentSessionData>> {
|
||||
let id = payment_session_data.id().unwrap_or_default();
|
||||
let id = ::stripe::PaymentIntentId::from_str(&id).map_err(|_| PError::NoPaymentIntentId)?;
|
||||
let intent = ::stripe::PaymentIntent::retrieve(&self.client, &id, &[])
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Failed to retrieve payment intent: {e}");
|
||||
PError::NoPaymentIntentId
|
||||
})?;
|
||||
Ok(Box::new(Intent(intent)))
|
||||
}
|
||||
|
||||
async fn cancel_payment(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<()> {
|
||||
let session =
|
||||
session_mut_ref::<Intent>(payment_session_data).ok_or_else(|| PError::InvalidType)?;
|
||||
let id = session.id.as_str();
|
||||
let intent = ::stripe::PaymentIntent::cancel(
|
||||
&self.client,
|
||||
id,
|
||||
::stripe::CancelPaymentIntent {
|
||||
cancellation_reason: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Cancel payment intent failed: {e}");
|
||||
PError::CancelFailed(id.to_owned())
|
||||
})?;
|
||||
session.0 = intent;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn payment_status(
|
||||
&mut self,
|
||||
payment_session_data: &mut Box<dyn PaymentSessionData>,
|
||||
) -> PResult<PaymentSessionStatus> {
|
||||
crate::payment_status(
|
||||
&self.client,
|
||||
payment_session_data
|
||||
.id()
|
||||
.ok_or_else(|| PError::NoPaymentIntentId)?,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| PError::HttpError)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct StripePrzelewy24Config {
|
||||
pub api_key: String,
|
||||
pub client: String,
|
||||
pub webhook_secret: String,
|
||||
pub capture: Option<bool>,
|
||||
pub automatic_payment_methods: Option<bool>,
|
||||
pub payment_description: Option<String>,
|
||||
pub setup_future_usage: SetupFutureUsage,
|
||||
}
|
66
crates/stripe_adapter/src/routes.rs
Normal file
66
crates/stripe_adapter/src/routes.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use stripe::{EventObject, EventType, Webhook, WebhookError};
|
||||
|
||||
#[actix_web::web::post("/stripe/hooks")]
|
||||
pub async fn stripe_hooks(req: HttpRequest, payload: web::Bytes) -> HttpResponse {
|
||||
handle_webhook(req, payload).unwrap();
|
||||
HttpResponse::Ok().finish()
|
||||
}
|
||||
|
||||
pub fn handle_webhook(req: HttpRequest, payload: web::Bytes) -> Result<(), WebhookError> {
|
||||
let payload_str = std::str::from_utf8(payload.borrow()).unwrap();
|
||||
|
||||
let stripe_signature = get_header_value(&req, "Stripe-Signature").unwrap_or_default();
|
||||
|
||||
if let Ok(event) = Webhook::construct_event(payload_str, stripe_signature, "whsec_xxxxx") {
|
||||
match event.type_ {
|
||||
EventType::AccountUpdated => {
|
||||
if let EventObject::Account(account) = event.data.object {
|
||||
handle_account_updated(account)?;
|
||||
}
|
||||
}
|
||||
EventType::CheckoutSessionCompleted => {
|
||||
if let EventObject::CheckoutSession(session) = event.data.object {
|
||||
handle_checkout_session(session)?;
|
||||
}
|
||||
}
|
||||
EventType::PaymentIntentSucceeded => {
|
||||
if let EventObject::PaymentIntent(intent) = event.data.object {
|
||||
handle_payment_intent(intent)?;
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
println!("Unknown event encountered in webhook: {:?}", event.type_);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Failed to construct webhook event, ensure your webhook secret is correct.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_header_value<'b>(req: &'b HttpRequest, key: &'b str) -> Option<&'b str> {
|
||||
req.headers().get(key)?.to_str().ok()
|
||||
}
|
||||
|
||||
fn handle_account_updated(account: stripe::Account) -> Result<(), WebhookError> {
|
||||
println!(
|
||||
"Received account updated webhook for account: {:?}",
|
||||
account.id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_checkout_session(session: stripe::CheckoutSession) -> Result<(), WebhookError> {
|
||||
println!(
|
||||
"Received checkout session completed webhook with id: {:?}",
|
||||
session.id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_payment_intent(_intent: stripe::PaymentIntent) -> Result<(), WebhookError> {
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user