// 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()); } }