raisfast 0.2.19

The last backend you'll ever need. Rust-powered headless CMS with built-in blog, ecommerce, wallet, payment and 4 plugin engines.
use crate::errors::app_error::AppResult;
use crate::models::payment_channel::PaymentChannel;
use crate::models::payment_order::{PaymentOrder, PaymentStatus};
use axum::http::HeaderMap;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone)]
pub struct ProviderResponse {
    pub provider_order_id: String,
    pub redirect_url: Option<String>,
    pub qr_code: Option<String>,
    pub client_secret: Option<String>,
}

#[derive(Debug, Clone)]
pub struct ProviderStatus {
    pub status: PaymentStatus,
    pub provider_tx_id: Option<String>,
    pub paid_at: Option<String>,
    pub amount: Option<i64>,
}

#[derive(Debug, Clone)]
pub struct RefundResponse {
    pub provider_refund_id: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallbackData {
    pub provider_order_id: String,
    pub status: PaymentStatus,
    pub amount: i64,
    pub provider_tx_id: Option<String>,
    pub paid_at: Option<String>,
}

#[async_trait::async_trait]
pub trait PaymentProvider: Send + Sync {
    fn name(&self) -> &str;
    async fn create(
        &self,
        channel: &PaymentChannel,
        order: &PaymentOrder,
        return_url: Option<&str>,
    ) -> AppResult<ProviderResponse>;
    async fn query(
        &self,
        channel: &PaymentChannel,
        provider_order_id: &str,
    ) -> AppResult<ProviderStatus>;
    async fn cancel(&self, channel: &PaymentChannel, provider_order_id: &str) -> AppResult<()>;
    async fn refund(
        &self,
        channel: &PaymentChannel,
        provider_order_id: &str,
        amount: i64,
        reason: Option<&str>,
    ) -> AppResult<RefundResponse>;
    async fn verify_callback(
        &self,
        channel: &PaymentChannel,
        headers: &HeaderMap,
        body: &[u8],
    ) -> AppResult<CallbackData>;
}