feat: Add new Rhai example demonstrating payment flow
- 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.
This commit is contained in:
214
heromodels/examples/payment_flow_example.rs
Normal file
214
heromodels/examples/payment_flow_example.rs
Normal file
@@ -0,0 +1,214 @@
|
||||
// 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());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user