- Add a new Rhai example showcasing complete payment flow for company registration. This includes company creation, payment record creation, successful payment processing, status updates, and handling failed and refunded payments. - Add new example demonstrating payment integration in Rhai scripting. This example showcases the usage of various payment status methods and verifies data from the database after processing payments. - Add new examples to Cargo.toml to facilitate building and running the examples. This makes it easier to integrate and test payment functionality using Rhai scripting.
215 lines
7.6 KiB
Rust
215 lines
7.6 KiB
Rust
// Payment Flow Example
|
|
// This example demonstrates the complete payment flow for company registration,
|
|
// including company creation with pending payment status, payment processing,
|
|
// and status transitions.
|
|
|
|
use heromodels::models::biz::{BusinessType, Company, CompanyStatus, Payment};
|
|
|
|
fn main() {
|
|
println!("=== Payment Flow Example ===");
|
|
println!("Demonstrating company registration with payment integration\n");
|
|
|
|
// Step 1: Create a company with pending payment status
|
|
println!("Step 1: Creating company with pending payment status");
|
|
let company = Company::new(
|
|
"TechStart Inc.".to_string(),
|
|
"REG-TS-2024-001".to_string(),
|
|
chrono::Utc::now().timestamp(),
|
|
)
|
|
.email("contact@techstart.com".to_string())
|
|
.phone("+1-555-0123".to_string())
|
|
.website("https://techstart.com".to_string())
|
|
.address("123 Startup Ave, Innovation City, IC 12345".to_string())
|
|
.business_type(BusinessType::Starter)
|
|
.industry("Technology".to_string())
|
|
.description("A promising tech startup focused on AI solutions".to_string())
|
|
// Note: status defaults to PendingPayment, so we don't need to set it explicitly
|
|
.fiscal_year_end("12-31".to_string());
|
|
|
|
println!(" Company: {}", company.name);
|
|
println!(" Status: {:?}", company.status);
|
|
println!(" Registration: {}", company.registration_number);
|
|
println!(" Company created successfully!\n");
|
|
|
|
// Step 2: Create a payment record for the company
|
|
println!("Step 2: Creating payment record");
|
|
let payment_intent_id = format!("pi_test_{}", chrono::Utc::now().timestamp());
|
|
let payment = Payment::new(
|
|
payment_intent_id.clone(),
|
|
1, // Mock company ID for this example
|
|
"yearly".to_string(),
|
|
500.0, // Setup fee
|
|
99.0, // Monthly fee
|
|
1688.0, // Total amount (setup + 12 months)
|
|
);
|
|
|
|
println!(" Payment Intent ID: {}", payment.payment_intent_id);
|
|
println!(" Company ID: {}", payment.company_id);
|
|
println!(" Payment Plan: {}", payment.payment_plan);
|
|
println!(" Setup Fee: ${:.2}", payment.setup_fee);
|
|
println!(" Monthly Fee: ${:.2}", payment.monthly_fee);
|
|
println!(" Total Amount: ${:.2}", payment.total_amount);
|
|
println!(" Status: {:?}", payment.status);
|
|
println!(" Payment record created successfully!\n");
|
|
|
|
// Step 3: Simulate payment processing
|
|
println!("Step 3: Processing payment...");
|
|
|
|
// Simulate some processing time
|
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
|
|
|
// Complete the payment with Stripe customer ID
|
|
let stripe_customer_id = Some(format!("cus_test_{}", chrono::Utc::now().timestamp()));
|
|
let completed_payment = payment.complete_payment(stripe_customer_id.clone());
|
|
|
|
println!(" Payment completed successfully!");
|
|
println!(" New Status: {:?}", completed_payment.status);
|
|
println!(
|
|
" Stripe Customer ID: {:?}",
|
|
completed_payment.stripe_customer_id
|
|
);
|
|
|
|
// Step 4: Update company status to Active
|
|
println!("\nStep 4: Updating company status to Active");
|
|
let active_company = company.status(CompanyStatus::Active);
|
|
|
|
println!(" Company: {}", active_company.name);
|
|
println!(" New Status: {:?}", active_company.status);
|
|
println!(" Company status updated successfully!\n");
|
|
|
|
// Step 5: Demonstrate payment status checks
|
|
println!("Step 5: Payment status verification");
|
|
println!(
|
|
" Is payment completed? {}",
|
|
completed_payment.is_completed()
|
|
);
|
|
println!(" Is payment pending? {}", completed_payment.is_pending());
|
|
println!(" Has payment failed? {}", completed_payment.has_failed());
|
|
println!(" Is payment refunded? {}", completed_payment.is_refunded());
|
|
|
|
// Step 6: Demonstrate failed payment scenario
|
|
println!("\nStep 6: Demonstrating failed payment scenario");
|
|
|
|
// Create another company
|
|
let failed_company = Company::new(
|
|
"FailCorp Ltd.".to_string(),
|
|
"REG-FC-2024-002".to_string(),
|
|
chrono::Utc::now().timestamp(),
|
|
)
|
|
.email("contact@failcorp.com".to_string())
|
|
.business_type(BusinessType::Single)
|
|
.industry("Consulting".to_string());
|
|
|
|
// Create payment for failed scenario
|
|
let failed_payment_intent = format!("pi_fail_{}", chrono::Utc::now().timestamp());
|
|
let failed_payment = Payment::new(
|
|
failed_payment_intent,
|
|
2, // Mock company ID
|
|
"monthly".to_string(),
|
|
250.0,
|
|
49.0,
|
|
299.0,
|
|
);
|
|
|
|
// Simulate payment failure
|
|
let failed_payment = failed_payment.fail_payment();
|
|
|
|
println!(" Failed Company: {}", failed_company.name);
|
|
println!(
|
|
" Company Status: {:?} (remains pending)",
|
|
failed_company.status
|
|
);
|
|
println!(" Payment Status: {:?}", failed_payment.status);
|
|
println!(" Payment failed: {}", failed_payment.has_failed());
|
|
|
|
println!("\n=== Payment Flow Example Complete ===");
|
|
println!("Summary:");
|
|
println!("- Created companies with PendingPayment status by default");
|
|
println!("- Processed successful payment and updated company to Active");
|
|
println!("- Demonstrated failed payment scenario");
|
|
println!("- All operations completed successfully without database persistence");
|
|
println!("- For database examples, see the Rhai examples or unit tests");
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_payment_flow() {
|
|
// Test the basic payment flow without database persistence
|
|
let company = Company::new(
|
|
"Test Company".to_string(),
|
|
"TEST-001".to_string(),
|
|
chrono::Utc::now().timestamp(),
|
|
);
|
|
|
|
// Verify default status is PendingPayment
|
|
assert_eq!(company.status, CompanyStatus::PendingPayment);
|
|
|
|
// Create payment
|
|
let payment = Payment::new(
|
|
"pi_test_123".to_string(),
|
|
1, // Mock company ID
|
|
"monthly".to_string(),
|
|
100.0,
|
|
50.0,
|
|
150.0,
|
|
);
|
|
|
|
// Verify default payment status is Pending
|
|
assert_eq!(payment.status, PaymentStatus::Pending);
|
|
assert!(payment.is_pending());
|
|
assert!(!payment.is_completed());
|
|
|
|
// Complete payment
|
|
let completed_payment = payment.complete_payment(Some("cus_test_123".to_string()));
|
|
assert_eq!(completed_payment.status, PaymentStatus::Completed);
|
|
assert!(completed_payment.is_completed());
|
|
assert!(!completed_payment.is_pending());
|
|
|
|
// Update company status
|
|
let active_company = company.status(CompanyStatus::Active);
|
|
assert_eq!(active_company.status, CompanyStatus::Active);
|
|
}
|
|
|
|
#[test]
|
|
fn test_payment_failure() {
|
|
let payment = Payment::new(
|
|
"pi_fail_123".to_string(),
|
|
1,
|
|
"yearly".to_string(),
|
|
500.0,
|
|
99.0,
|
|
1688.0,
|
|
);
|
|
|
|
let failed_payment = payment.fail_payment();
|
|
assert_eq!(failed_payment.status, PaymentStatus::Failed);
|
|
assert!(failed_payment.has_failed());
|
|
assert!(!failed_payment.is_completed());
|
|
}
|
|
|
|
#[test]
|
|
fn test_payment_refund() {
|
|
let payment = Payment::new(
|
|
"pi_refund_123".to_string(),
|
|
1,
|
|
"monthly".to_string(),
|
|
250.0,
|
|
49.0,
|
|
299.0,
|
|
);
|
|
|
|
// First complete the payment
|
|
let completed_payment = payment.complete_payment(Some("cus_123".to_string()));
|
|
assert!(completed_payment.is_completed());
|
|
|
|
// Then refund it
|
|
let refunded_payment = completed_payment.refund_payment();
|
|
assert_eq!(refunded_payment.status, PaymentStatus::Refunded);
|
|
assert!(refunded_payment.is_refunded());
|
|
assert!(!refunded_payment.is_completed());
|
|
}
|
|
}
|