Config
This commit is contained in:
parent
f55f2c4a0d
commit
9d6534c2a2
4
.env
4
.env
@ -1,7 +1,7 @@
|
|||||||
DATABASE_URL=postgres://postgres@localhost/bazzar
|
DATABASE_URL=postgres://postgres@localhost/bazzar
|
||||||
PASS_SALT=18CHwV7eGFAea16z+qMKZg
|
PASS_SALT=18CHwV7eGFAea16z+qMKZg
|
||||||
RUST_LOG=debug
|
RUST_LOG=debug
|
||||||
KEY_SECRET="NEPJs#8jjn8SK8GC7QEC^*P844UgsyEbQB8mRWXkT%3mPrwewZoc25MMby9H#R*w2KzaQgMkk#Pif$kxrLy*N5L!Ch%jxbWoa%gb"
|
SESSION_SECRET="NEPJs#8jjn8SK8GC7QEC^*P844UgsyEbQB8mRWXkT%3mPrwewZoc25MMby9H#R*w2KzaQgMkk#Pif$kxrLy*N5L!Ch%jxbWoa%gb"
|
||||||
JWT_SECRET="42^iFq&ZnQbUf!hwGWXd&CpyY6QQyJmkPU%esFCvne5&Ejcb3nJ4&GyHZp!MArZLf^9*5c6!!VgM$iZ8T%d#&bWTi&xbZk2S@4RN"
|
JWT_SECRET="42^iFq&ZnQbUf!hwGWXd&CpyY6QQyJmkPU%esFCvne5&Ejcb3nJ4&GyHZp!MArZLf^9*5c6!!VgM$iZ8T%d#&bWTi&xbZk2S@4RN"
|
||||||
PGDATESTYLE=
|
PGDATESTYLE=
|
||||||
|
|
||||||
@ -12,3 +12,5 @@ SMTP_FROM=adrian.wozniak@ita-prog.pl
|
|||||||
PAYU_CLIENT_ID="145227"
|
PAYU_CLIENT_ID="145227"
|
||||||
PAYU_CLIENT_SECRET="12f071174cb7eb79d4aac5bc2f07563f"
|
PAYU_CLIENT_SECRET="12f071174cb7eb79d4aac5bc2f07563f"
|
||||||
PAYU_CLIENT_MERCHANT_ID=300746
|
PAYU_CLIENT_MERCHANT_ID=300746
|
||||||
|
|
||||||
|
WEB_HOST=https://bazzar.ita-prog.pl
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
bazzar.toml
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use actix::Addr;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use pay_u::{MerchantPosId, OrderCreateRequest};
|
use pay_u::{MerchantPosId, OrderCreateRequest};
|
||||||
|
|
||||||
use crate::model::{Price, Quantity};
|
use crate::database;
|
||||||
|
use crate::database::Database;
|
||||||
|
use crate::model::{AccountId, Price, ProductId, Quantity, QuantityUnit, ShoppingCartId};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! pay_async_handler {
|
macro_rules! pay_async_handler {
|
||||||
@ -13,8 +16,9 @@ macro_rules! pay_async_handler {
|
|||||||
|
|
||||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
use actix::WrapFuture;
|
use actix::WrapFuture;
|
||||||
let db = self.client.clone();
|
let client = self.client.clone();
|
||||||
Box::pin(async { $async(msg, db).await }.into_actor(self))
|
let db = self.db.clone();
|
||||||
|
Box::pin(async { $async(msg, client, db).await }.into_actor(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -26,6 +30,8 @@ pub type PayUClient = Arc<Mutex<pay_u::Client>>;
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
PayU(#[from] pay_u::Error),
|
PayU(#[from] pay_u::Error),
|
||||||
|
#[error("Failed to create order")]
|
||||||
|
CreateOrder,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
@ -33,6 +39,7 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PaymentManager {
|
pub struct PaymentManager {
|
||||||
client: PayUClient,
|
client: PayUClient,
|
||||||
|
db: Addr<Database>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaymentManager {
|
impl PaymentManager {
|
||||||
@ -40,6 +47,7 @@ impl PaymentManager {
|
|||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
client_secret: ClientSecret,
|
client_secret: ClientSecret,
|
||||||
merchant_pos_id: MerchantPosId,
|
merchant_pos_id: MerchantPosId,
|
||||||
|
db: Addr<Database>,
|
||||||
) -> Result<Self>
|
) -> Result<Self>
|
||||||
where
|
where
|
||||||
ClientId: Into<pay_u::ClientId>,
|
ClientId: Into<pay_u::ClientId>,
|
||||||
@ -50,6 +58,7 @@ impl PaymentManager {
|
|||||||
client.authorize().await?;
|
client.authorize().await?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
client: Arc::new(Mutex::new(client)),
|
client: Arc::new(Mutex::new(client)),
|
||||||
|
db,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,8 +94,10 @@ impl From<Buyer> for pay_u::Buyer {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Product {
|
pub struct Product {
|
||||||
|
pub id: ProductId,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub unit_price: Price,
|
pub unit_price: Price,
|
||||||
|
pub quantity_unit: QuantityUnit,
|
||||||
pub quantity: Quantity,
|
pub quantity: Quantity,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +116,8 @@ pub struct RequestPayment {
|
|||||||
pub description: String,
|
pub description: String,
|
||||||
pub buyer: Buyer,
|
pub buyer: Buyer,
|
||||||
pub customer_ip: String,
|
pub customer_ip: String,
|
||||||
|
pub buyer_id: AccountId,
|
||||||
|
pub shopping_cart_id: ShoppingCartId,
|
||||||
}
|
}
|
||||||
|
|
||||||
pay_async_handler!(RequestPayment, request_payment, pay_u::OrderId);
|
pay_async_handler!(RequestPayment, request_payment, pay_u::OrderId);
|
||||||
@ -112,8 +125,36 @@ pay_async_handler!(RequestPayment, request_payment, pay_u::OrderId);
|
|||||||
pub(crate) async fn request_payment(
|
pub(crate) async fn request_payment(
|
||||||
msg: RequestPayment,
|
msg: RequestPayment,
|
||||||
client: PayUClient,
|
client: PayUClient,
|
||||||
|
db: Addr<Database>,
|
||||||
) -> Result<pay_u::OrderId> {
|
) -> Result<pay_u::OrderId> {
|
||||||
let client = &mut *client.lock();
|
let db_order = match db
|
||||||
|
.send(database::CreateAccountOrder {
|
||||||
|
buyer_id: msg.buyer_id,
|
||||||
|
items: msg
|
||||||
|
.products
|
||||||
|
.iter()
|
||||||
|
.map(|product| database::create_order::OrderItem {
|
||||||
|
product_id: product.id,
|
||||||
|
quantity: product.quantity,
|
||||||
|
quantity_unit: product.quantity_unit,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
shopping_cart_id: msg.shopping_cart_id,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(Ok(order)) => order,
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
log::error!("{e}");
|
||||||
|
return Err(Error::CreateOrder);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("{e:?}");
|
||||||
|
return Err(Error::CreateOrder);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut client = client.lock();
|
||||||
let order = client
|
let order = client
|
||||||
.create_order(
|
.create_order(
|
||||||
OrderCreateRequest::new(msg.buyer.into(), msg.customer_ip, msg.currency)
|
OrderCreateRequest::new(msg.buyer.into(), msg.customer_ip, msg.currency)
|
||||||
|
272
api/src/config.rs
Normal file
272
api/src/config.rs
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
trait Example: Sized {
|
||||||
|
fn example() -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
pub struct PaymentConfig {
|
||||||
|
payu_client_id: Option<pay_u::ClientId>,
|
||||||
|
payu_client_secret: Option<pay_u::ClientSecret>,
|
||||||
|
payu_client_merchant_id: Option<pay_u::MerchantPosId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for PaymentConfig {
|
||||||
|
fn example() -> Self {
|
||||||
|
Self {
|
||||||
|
payu_client_id: Some(pay_u::ClientId::new(
|
||||||
|
"Create payu account and copy here client_id",
|
||||||
|
)),
|
||||||
|
payu_client_secret: Some(pay_u::ClientSecret::new(
|
||||||
|
"Create payu account and copy here client_secret",
|
||||||
|
)),
|
||||||
|
/// "Create payu account and copy here merchant id"
|
||||||
|
payu_client_merchant_id: Some(pay_u::MerchantPosId::from(0)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaymentConfig {
|
||||||
|
pub fn payu_client_id(&self) -> pay_u::ClientId {
|
||||||
|
self.payu_client_id
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("PAYU_CLIENT_ID").ok().map(pay_u::ClientId))
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!("payment config payu_client_id nor PAYU_CLIENT_ID env was given")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn payu_client_secret(&self) -> pay_u::ClientSecret {
|
||||||
|
self.payu_client_secret
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| {
|
||||||
|
std::env::var("PAYU_CLIENT_SECRET")
|
||||||
|
.ok()
|
||||||
|
.map(pay_u::ClientSecret)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!("payment config payu_client_secret nor PAYU_CLIENT_SECRET env was given")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn payu_client_merchant_id(&self) -> pay_u::MerchantPosId {
|
||||||
|
self.payu_client_merchant_id
|
||||||
|
.or_else(|| std::env::var("PAYU_CLIENT_MERCHANT_ID").ok().and_then(|s| s.parse::<i32>().ok()).map(pay_u::MerchantPosId))
|
||||||
|
.unwrap_or_else(|| panic!("payment config payu_client_merchant_id nor PAYU_CLIENT_MERCHANT_ID env was given"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
pub struct WebConfig {
|
||||||
|
/// Host name
|
||||||
|
/// Example: https://foo.bar
|
||||||
|
host: Option<String>,
|
||||||
|
/// Encrypt password salt
|
||||||
|
pass_salt: Option<String>,
|
||||||
|
/// Used by redis to save admin session across actors
|
||||||
|
session_secret: Option<String>,
|
||||||
|
/// Encrypt JWT
|
||||||
|
jwt_secret: Option<String>,
|
||||||
|
bind: Option<String>,
|
||||||
|
port: Option<u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for WebConfig {
|
||||||
|
fn example() -> Self {
|
||||||
|
Self {
|
||||||
|
host: Some(String::from("https://your.comain.com")),
|
||||||
|
pass_salt: Some(String::from("Generate it with bazzar generate-hash")),
|
||||||
|
session_secret: Some(String::from("100 characters long random string")),
|
||||||
|
jwt_secret: Some(String::from("100 characters long random string")),
|
||||||
|
bind: Some(String::from("0.0.0.0")),
|
||||||
|
port: Some(8080),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebConfig {
|
||||||
|
pub fn host(&self) -> String {
|
||||||
|
self.host
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("WEB_HOST").ok())
|
||||||
|
.unwrap_or_else(|| panic!("web host config nor WEB_HOST env was not given"))
|
||||||
|
}
|
||||||
|
pub fn pass_salt(&self) -> String {
|
||||||
|
self.pass_salt
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("PASS_SALT").ok())
|
||||||
|
.unwrap_or_else(|| panic!("Web config pass_salt nor PASS_SALT env was given"))
|
||||||
|
}
|
||||||
|
pub fn session_secret(&self) -> String {
|
||||||
|
self.session_secret
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("SESSION_SECRET").ok())
|
||||||
|
.unwrap_or_else(|| panic!("Web config session_secret nor SESSION_SECRET env was given"))
|
||||||
|
}
|
||||||
|
pub fn jwt_secret(&self) -> String {
|
||||||
|
self.jwt_secret
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("JWT_SECRET").ok())
|
||||||
|
.unwrap_or_else(|| panic!("Web config jwt_secret nor JWT_SECRET env was given"))
|
||||||
|
}
|
||||||
|
pub fn bind(&self) -> Option<String> {
|
||||||
|
self.bind
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("BAZZAR_BIND").ok())
|
||||||
|
}
|
||||||
|
pub fn port(&self) -> Option<u16> {
|
||||||
|
self.port.as_ref().copied().or_else(|| {
|
||||||
|
std::env::var("BAZZAR_PORT")
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| s.parse::<u16>().ok())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
pub struct MailConfig {
|
||||||
|
sendgrid_secret: Option<String>,
|
||||||
|
sendgrid_api_key: Option<String>,
|
||||||
|
smtp_from: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for MailConfig {
|
||||||
|
fn example() -> Self {
|
||||||
|
Self {
|
||||||
|
sendgrid_secret: Some(String::from(
|
||||||
|
"Create sendgrid account and copy credentials here",
|
||||||
|
)),
|
||||||
|
sendgrid_api_key: Some(String::from(
|
||||||
|
"Create sendgrid account and copy credentials here",
|
||||||
|
)),
|
||||||
|
smtp_from: Some(String::from(
|
||||||
|
"Valid sendgrid authorized email address. Example: contact@example.com",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MailConfig {
|
||||||
|
pub fn sendgrid_secret(&self) -> String {
|
||||||
|
self.sendgrid_secret
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("SENDGRID_SECRET").ok())
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!("Mail sendgrid_secret config nor SENDGRID_SECRET env was given")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn sendgrid_api_key(&self) -> String {
|
||||||
|
self.sendgrid_api_key
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("SENDGRID_API_KEY").ok())
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!("Mail sendgrid_api_key config nor SENDGRID_API_KEY env was given")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn smtp_from(&self) -> String {
|
||||||
|
self.smtp_from
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("SMTP_FROM").ok())
|
||||||
|
.unwrap_or_else(|| panic!("Mail smtp_from config nor SMTP_FROM env was given"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
pub struct DatabaseConfig {
|
||||||
|
url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for DatabaseConfig {
|
||||||
|
fn example() -> Self {
|
||||||
|
Self {
|
||||||
|
url: Some(String::from("postgres://postgres@localhost/bazzar")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DatabaseConfig {
|
||||||
|
pub fn url(&self) -> String {
|
||||||
|
self.url
|
||||||
|
.as_ref()
|
||||||
|
.cloned()
|
||||||
|
.or_else(|| std::env::var("DATABASE_URL").ok())
|
||||||
|
.unwrap_or_else(|| panic!("Database url nor DATABASE_URL env was given"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct AppConfig {
|
||||||
|
payment: PaymentConfig,
|
||||||
|
web: WebConfig,
|
||||||
|
mail: MailConfig,
|
||||||
|
database: DatabaseConfig,
|
||||||
|
#[serde(skip)]
|
||||||
|
config_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for AppConfig {
|
||||||
|
fn example() -> Self {
|
||||||
|
Self {
|
||||||
|
payment: PaymentConfig::example(),
|
||||||
|
web: WebConfig::example(),
|
||||||
|
mail: MailConfig::example(),
|
||||||
|
database: DatabaseConfig::example(),
|
||||||
|
config_path: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppConfig {
|
||||||
|
pub fn payment(&self) -> &PaymentConfig {
|
||||||
|
&self.payment
|
||||||
|
}
|
||||||
|
pub fn web(&self) -> &WebConfig {
|
||||||
|
&self.web
|
||||||
|
}
|
||||||
|
pub fn mail(&self) -> &MailConfig {
|
||||||
|
&self.mail
|
||||||
|
}
|
||||||
|
pub fn database(&self) -> &DatabaseConfig {
|
||||||
|
&self.database
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AppConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
payment: Default::default(),
|
||||||
|
web: WebConfig::default(),
|
||||||
|
mail: Default::default(),
|
||||||
|
database: DatabaseConfig::default(),
|
||||||
|
config_path: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(config_path: &str) -> AppConfig {
|
||||||
|
match std::fs::read_to_string(config_path) {
|
||||||
|
Ok(c) => toml::from_str(&c).unwrap(),
|
||||||
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||||
|
let config = AppConfig::example();
|
||||||
|
std::fs::write(config_path, toml::to_string_pretty(&config).unwrap()).unwrap();
|
||||||
|
config
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("{e:?}");
|
||||||
|
panic!("Config file was not found at path {config_path:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(config_path: &str, config: &mut AppConfig) {
|
||||||
|
config.config_path = String::from(config_path);
|
||||||
|
std::fs::write(config_path, toml::to_string_pretty(&config).unwrap()).unwrap();
|
||||||
|
}
|
@ -20,6 +20,7 @@ use crate::logic::encrypt_password;
|
|||||||
use crate::model::{Email, Login, PassHash, Password, Role};
|
use crate::model::{Email, Login, PassHash, Password, Role};
|
||||||
|
|
||||||
pub mod actors;
|
pub mod actors;
|
||||||
|
pub mod config;
|
||||||
pub mod logic;
|
pub mod logic;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
@ -174,12 +175,14 @@ impl Config {
|
|||||||
|
|
||||||
async fn server(opts: ServerOpts) -> Result<()> {
|
async fn server(opts: ServerOpts) -> Result<()> {
|
||||||
let secret_key = {
|
let secret_key = {
|
||||||
let key_secret = std::env::var("KEY_SECRET")
|
let key_secret = std::env::var("SESSION_SECRET")
|
||||||
.expect("session requires secret key with 64 or more characters");
|
.expect("session requires secret key with 64 or more characters");
|
||||||
Key::from(key_secret.as_bytes())
|
Key::from(key_secret.as_bytes())
|
||||||
};
|
};
|
||||||
let redis_connection_string = "127.0.0.1:6379";
|
let redis_connection_string = "127.0.0.1:6379";
|
||||||
|
|
||||||
|
let app_config = crate::config::load("./bazzar.toml");
|
||||||
|
|
||||||
let config = Arc::new(Config::load());
|
let config = Arc::new(Config::load());
|
||||||
let db = database::Database::build(&opts.db_url()).await?.start();
|
let db = database::Database::build(&opts.db_url()).await?.start();
|
||||||
let token_manager = token_manager::TokenManager::new(db.clone()).start();
|
let token_manager = token_manager::TokenManager::new(db.clone()).start();
|
||||||
@ -193,7 +196,7 @@ async fn server(opts: ServerOpts) -> Result<()> {
|
|||||||
.parse::<i32>()
|
.parse::<i32>()
|
||||||
.map(MerchantPosId::from)
|
.map(MerchantPosId::from)
|
||||||
.expect("Variable PAYU_CLIENT_MERCHANT_ID must be number");
|
.expect("Variable PAYU_CLIENT_MERCHANT_ID must be number");
|
||||||
payment_manager::PaymentManager::build(client_id, client_secret, merchant_id)
|
payment_manager::PaymentManager::build(client_id, client_secret, merchant_id, db.clone())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to start payment manager")
|
.expect("Failed to start payment manager")
|
||||||
.start()
|
.start()
|
||||||
@ -216,7 +219,10 @@ async fn server(opts: ServerOpts) -> Result<()> {
|
|||||||
.configure(routes::configure)
|
.configure(routes::configure)
|
||||||
// .default_service(web::to(HttpResponse::Ok))
|
// .default_service(web::to(HttpResponse::Ok))
|
||||||
})
|
})
|
||||||
.bind((opts.bind, opts.port))
|
.bind((
|
||||||
|
app_config.web().bind().unwrap_or(opts.bind),
|
||||||
|
app_config.web().port().unwrap_or(opts.port),
|
||||||
|
))
|
||||||
.map_err(Error::Boot)?
|
.map_err(Error::Boot)?
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
|
@ -131,12 +131,12 @@ impl Default for Audience {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(sqlx::Type, Serialize, Deserialize, Debug, Deref, From)]
|
#[derive(sqlx::Type, Serialize, Deserialize, Default, Debug, Copy, Clone, Deref, From)]
|
||||||
#[sqlx(transparent)]
|
#[sqlx(transparent)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Price(NonNegative);
|
pub struct Price(NonNegative);
|
||||||
|
|
||||||
#[derive(sqlx::Type, Serialize, Deserialize, Default, Debug, Deref, From)]
|
#[derive(sqlx::Type, Serialize, Deserialize, Default, Debug, Copy, Clone, Deref, From)]
|
||||||
#[sqlx(transparent)]
|
#[sqlx(transparent)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Quantity(NonNegative);
|
pub struct Quantity(NonNegative);
|
||||||
@ -200,7 +200,7 @@ impl<'de> serde::Deserialize<'de> for Email {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(sqlx::Type, Serialize, Default, Debug, Deref, Display)]
|
#[derive(sqlx::Type, Serialize, Default, Debug, Copy, Clone, Deref, Display)]
|
||||||
#[sqlx(transparent)]
|
#[sqlx(transparent)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct NonNegative(i32);
|
pub struct NonNegative(i32);
|
||||||
|
@ -1,5 +1,2 @@
|
|||||||
ALTER TABLE accounts
|
ALTER TABLE accounts
|
||||||
ADD COLUMN customer_id uuid not null default gen_random_uuid();
|
ADD COLUMN customer_id uuid not null default gen_random_uuid();
|
||||||
|
|
||||||
ALTER TABLE account_orders
|
|
||||||
ADD COLUMN order_id varchar unique;
|
|
||||||
|
2
db/migrate/202204271359_add_order_ext_id.sql
Normal file
2
db/migrate/202204271359_add_order_ext_id.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE account_orders
|
||||||
|
ADD COLUMN order_ext_id uuid not null default uuid_generate_v4();
|
Loading…
Reference in New Issue
Block a user