2022-12-01 17:39:06 +01:00
|
|
|
// use rumqttc::QoS;
|
|
|
|
|
2022-12-16 15:21:56 +01:00
|
|
|
pub use payment_adapter::*;
|
2022-12-01 17:39:06 +01:00
|
|
|
// use crate::AsyncClient;
|
|
|
|
|
|
|
|
pub static CLIENT_NAME: &str = "payments";
|
|
|
|
|
|
|
|
#[derive(Debug, thiserror::Error, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub enum Error {
|
|
|
|
#[error("Something went wrong")]
|
|
|
|
InternalServerError,
|
2022-12-18 21:31:39 +01:00
|
|
|
#[error("Unknown payment adapter {0:?}")]
|
|
|
|
UnknownAdapter(String),
|
|
|
|
#[error("Payment failed")]
|
|
|
|
PaymentFailed,
|
|
|
|
#[error("Payment adapter returned invalid response data")]
|
|
|
|
MalformedCreatePaymentResult,
|
2022-12-01 17:39:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
pub enum Topic {
|
2022-12-16 15:21:56 +01:00
|
|
|
Pending,
|
|
|
|
WaitingForConfirmation,
|
|
|
|
Completed,
|
|
|
|
Canceled,
|
2022-12-01 17:39:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Topic {
|
|
|
|
pub fn to_str(self) -> &'static str {
|
|
|
|
match self {
|
2022-12-16 15:21:56 +01:00
|
|
|
Topic::Completed => "payments/completed",
|
|
|
|
Topic::Canceled => "payments/canceled",
|
|
|
|
Topic::Pending => "payments/pending",
|
|
|
|
Topic::WaitingForConfirmation => "payments/waiting_for_confirmation",
|
2022-12-01 17:39:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Into<String> for Topic {
|
|
|
|
fn into(self) -> String {
|
|
|
|
self.to_str().into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'s> PartialEq<&'s str> for Topic {
|
|
|
|
fn eq(&self, other: &&'s str) -> bool {
|
|
|
|
self.to_str() == *other
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq<String> for Topic {
|
|
|
|
fn eq(&self, other: &String) -> bool {
|
|
|
|
self.to_str() == other.as_str()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub mod start_payment {
|
|
|
|
use super::Error;
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
2022-12-16 15:21:56 +01:00
|
|
|
pub struct Input {
|
|
|
|
pub adapter_name: String,
|
|
|
|
pub create_payment: payment_adapter::CreatePayment,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Details {
|
|
|
|
pub redirect_url: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type Output = Result<Details, Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub mod notification {
|
|
|
|
use super::Error;
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Input {
|
|
|
|
pub adapter_name: String,
|
2022-12-16 17:32:04 +01:00
|
|
|
pub body: Vec<u8>,
|
2022-12-16 15:21:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Details {}
|
|
|
|
|
|
|
|
pub type Output = Result<Details, Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub mod cancel {
|
|
|
|
use model::Price;
|
|
|
|
|
|
|
|
use super::Error;
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub enum RefundType {
|
|
|
|
/// Refund entire payment
|
|
|
|
Full,
|
|
|
|
/// Refund only part given in enum
|
|
|
|
Partial(Price),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Input {
|
|
|
|
pub adapter_name: String,
|
|
|
|
pub refund: RefundType,
|
|
|
|
pub provider_order_id: String,
|
|
|
|
pub description: String,
|
|
|
|
}
|
2022-12-01 17:39:06 +01:00
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Details {}
|
|
|
|
|
|
|
|
pub type Output = Result<Details, Error>;
|
|
|
|
}
|
|
|
|
|
2022-12-16 15:21:56 +01:00
|
|
|
/// List of available payment adapters
|
|
|
|
pub mod adapters {
|
|
|
|
use super::Error;
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Input {}
|
|
|
|
|
|
|
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Details {
|
|
|
|
pub names: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type Output = Result<Details, Error>;
|
|
|
|
}
|
|
|
|
|
2022-12-01 17:39:06 +01:00
|
|
|
pub mod rpc {
|
|
|
|
use config::SharedAppConfig;
|
|
|
|
|
2022-12-16 15:21:56 +01:00
|
|
|
use crate::payments::{adapters, cancel, notification, start_payment};
|
2022-12-01 17:39:06 +01:00
|
|
|
|
|
|
|
#[tarpc::service]
|
|
|
|
pub trait Payments {
|
2022-12-16 15:21:56 +01:00
|
|
|
/// User manually started payment procedure
|
2022-12-01 17:39:06 +01:00
|
|
|
async fn start_payment(input: start_payment::Input) -> start_payment::Output;
|
2022-12-16 15:21:56 +01:00
|
|
|
|
|
|
|
/// User manually cancelled order
|
|
|
|
async fn cancel(input: cancel::Input) -> cancel::Output;
|
|
|
|
|
|
|
|
/// Received update status notification from payment service
|
|
|
|
async fn notification(input: notification::Input) -> notification::Output;
|
|
|
|
|
|
|
|
/// List of available adapters
|
|
|
|
async fn adapters(input: adapters::Input) -> adapters::Output;
|
2022-12-01 17:39:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn create_client(config: SharedAppConfig) -> PaymentsClient {
|
|
|
|
use tarpc::client;
|
|
|
|
use tarpc::tokio_serde::formats::Bincode;
|
|
|
|
|
|
|
|
let l = config.lock();
|
2022-12-18 21:31:39 +01:00
|
|
|
let addr = l.payment().rpc_addr();
|
2022-12-01 17:39:06 +01:00
|
|
|
|
|
|
|
let transport = tarpc::serde_transport::tcp::connect(addr, Bincode::default);
|
|
|
|
|
|
|
|
let client = PaymentsClient::new(
|
|
|
|
client::Config::default(),
|
|
|
|
transport.await.expect("Failed to connect to server"),
|
|
|
|
)
|
|
|
|
.spawn();
|
|
|
|
|
|
|
|
client
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub mod mqtt {
|
|
|
|
use config::SharedAppConfig;
|
|
|
|
use rumqttc::EventLoop;
|
|
|
|
|
|
|
|
use super::CLIENT_NAME;
|
|
|
|
use crate::AsyncClient;
|
|
|
|
|
|
|
|
pub fn create_client(config: SharedAppConfig) -> (AsyncClient, EventLoop) {
|
2022-12-18 21:31:39 +01:00
|
|
|
crate::mqtt::create_client(CLIENT_NAME, config.lock().payment().mqtt_addr())
|
2022-12-01 17:39:06 +01:00
|
|
|
}
|
|
|
|
}
|