diff --git a/README.md b/README.md index 6675446..8cb3263 100644 --- a/README.md +++ b/README.md @@ -5843,7 +5843,7 @@ fn merchant_credential_generation_example() -> Result<(), Box> { let client = blockchyp::Client::new(creds); let request = blockchyp::MerchantCredentialGenerationRequest{ - + merchant_id: "".to_string(), ..Default::default() }; let (response, err) = client.merchant_credential_generation(&request); @@ -5869,6 +5869,73 @@ fn main() -> Result<(), Box> { ``` +#### Submit Application + + + +* **API Credential Types:** Partner +* **Required Role:** INVITE MERCHANT + +This is a partner level API that can be used to submit applications to add new merchant accounts. The application requires a significant amount of detailed information about the merchant and their business. Rather than providing an exhaustive list of required fields, we recommend submitting as much information as possible in your initial request. + +If any required fields are missing or if there are any validation errors, the API will return specific error messages indicating which fields need to be addressed. Simply review these validation errors, fill in the missing information or correct any errors, and resubmit the application. + +Key areas of information include: +- Business details (name, type, tax information) +- Contact information +- Address information (physical and mailing) +- Owner details +- Bank account information +- Transaction volume estimates +- Operational settings (timezone, batch close time, etc.) + +**Note:** Some fields may be conditionally required based on the values of other fields. The validation process will guide you through ensuring all necessary information is provided. + + + + +```rust +use blockchyp; +use std::error::Error; + +fn submit_application_example() -> Result<(), Box> { + // sample credentials + let creds = blockchyp::APICredentials { + api_key: "ZDSMMZLGRPBPRTJUBTAFBYZ33Q".to_string(), + bearer_token: "ZLBW5NR4U5PKD5PNP3ZP3OZS5U".to_string(), + signing_key: "9c6a5e8e763df1c9256e3d72bd7f53dfbd07312938131c75b3bfd254da787947".to_string(), + }; + + // instantiate the client + let client = blockchyp::Client::new(creds); + + let request = blockchyp::SubmitApplicationRequest{ + + ..Default::default() + }; + let (response, err) = client.submit_application(&request); + + if let Some(e) = err { + eprintln!("Unexpected error occurred: {:?}", e); + return Err(e) + } + + if response.success { + println!("Success"); + } + + println!("Response: {:?}", response); + Ok(()) +} + +fn main() -> Result<(), Box> { + submit_application_example()?; + println!("Example completed successfully!"); + Ok(()) +} + +``` + diff --git a/examples/merchant_credential_generation_example.rs b/examples/merchant_credential_generation_example.rs index da646bd..efe88fd 100644 --- a/examples/merchant_credential_generation_example.rs +++ b/examples/merchant_credential_generation_example.rs @@ -13,7 +13,7 @@ fn merchant_credential_generation_example() -> Result<(), Box> { let client = blockchyp::Client::new(creds); let request = blockchyp::MerchantCredentialGenerationRequest{ - + merchant_id: "".to_string(), ..Default::default() }; let (response, err) = client.merchant_credential_generation(&request); diff --git a/examples/submit_application_example.rs b/examples/submit_application_example.rs new file mode 100644 index 0000000..68fe425 --- /dev/null +++ b/examples/submit_application_example.rs @@ -0,0 +1,38 @@ +use blockchyp; +use std::error::Error; + +fn submit_application_example() -> Result<(), Box> { + // sample credentials + let creds = blockchyp::APICredentials { + api_key: "ZDSMMZLGRPBPRTJUBTAFBYZ33Q".to_string(), + bearer_token: "ZLBW5NR4U5PKD5PNP3ZP3OZS5U".to_string(), + signing_key: "9c6a5e8e763df1c9256e3d72bd7f53dfbd07312938131c75b3bfd254da787947".to_string(), + }; + + // instantiate the client + let client = blockchyp::Client::new(creds); + + let request = blockchyp::SubmitApplicationRequest{ + + ..Default::default() + }; + let (response, err) = client.submit_application(&request); + + if let Some(e) = err { + eprintln!("Unexpected error occurred: {:?}", e); + return Err(e) + } + + if response.success { + println!("Success"); + } + + println!("Response: {:?}", response); + Ok(()) +} + +fn main() -> Result<(), Box> { + submit_application_example()?; + println!("Example completed successfully!"); + Ok(()) +} diff --git a/src/blockchyp.rs b/src/blockchyp.rs index b7435f4..567f59f 100644 --- a/src/blockchyp.rs +++ b/src/blockchyp.rs @@ -1969,6 +1969,28 @@ impl Client { None }; + (response, err) + } + /// Submits and application to add a new merchant account. + pub fn submit_application(&self, request: &SubmitApplicationRequest) -> (Acknowledgement, Option>) { + let mut response = Acknowledgement::default(); + let response_err = self.dashboard_request("/api/submit-application", "POST", request, &mut response, Some(request.timeout)); + + let err = if let Err(e) = response_err { + if let Some(reqwest_err) = e.downcast_ref::() { + if reqwest_err.is_timeout() { + response.response_description = RESPONSE_TIMED_OUT.to_string(); + } else { + response.response_description = e.to_string(); + } + } else { + response.response_description = e.to_string(); + } + Some(e) + } else { + None + }; + (response, err) } /// Adds a test merchant account. diff --git a/src/models.rs b/src/models.rs index 454d260..6e341ce 100644 --- a/src/models.rs +++ b/src/models.rs @@ -7289,6 +7289,387 @@ pub struct AggregateBillingLineItemStats { } +/// Models an individual with 25% or more ownership interest in a company. +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct Owner { + /// The first name of the owner. + #[serde(rename = "firstName")] + pub first_name: String, + /// The last name of the owner. + #[serde(rename = "lastName")] + pub last_name: String, + /// The job title of the owner. + #[serde(rename = "jobTitle")] + pub job_title: String, + /// The tax identification number (SSN) of the owner. + #[serde(rename = "taxIdNumber")] + pub tax_id_number: String, + /// The phone number of the owner. + #[serde(rename = "phoneNumber")] + pub phone_number: String, + /// The date of birth of the owner in mm/dd/yyyy format. + #[serde(rename = "dob")] + pub dob: String, + /// The percentage of ownership. + #[serde(rename = "ownership")] + pub ownership: String, + /// The address of the owner. + #[serde(rename = "address")] + pub address: Address, + /// The email address of the owner. + #[serde(rename = "email")] + pub email: String, + /// A single line representation of the owner's address. + #[serde(rename = "singleLineAddress")] + pub single_line_address: String, + /// The type of entity this owner represents. + #[serde(rename = "entityType")] + pub entity_type: String, + /// The driver's license number of the owner. + #[serde(rename = "dlNumber")] + pub dl_number: String, + /// The state that issued the owner's driver's license. + #[serde(rename = "dlStateOrProvince")] + pub dl_state_or_province: String, + /// The expiration date of the owner's driver's license. + #[serde(rename = "dlExpiration")] + pub dl_expiration: String, + +} + +/// Models a bank account associated with an application. +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct ApplicationAccount { + /// The name of the bank account. + #[serde(rename = "name")] + pub name: String, + /// The name of the bank. + #[serde(rename = "bank")] + pub bank: String, + /// The name of the account holder. + #[serde(rename = "accountHolderName")] + pub account_holder_name: String, + /// The routing number of the bank. + #[serde(rename = "routingNumber")] + pub routing_number: String, + /// The account number. + #[serde(rename = "accountNumber")] + pub account_number: String, + +} + +/// Models a merchant application form to add a merchant account. +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct MerchantApplication { + /// The invite code for the merchant. + #[serde(rename = "inviteCode")] + pub invite_code: String, + /// The business name your customers know you by (DBA Name). + #[serde(rename = "dbaName")] + pub dba_name: String, + /// The name of the legal entity you file your taxes under. + #[serde(rename = "corporateName")] + pub corporate_name: String, + /// The business website. + #[serde(rename = "webSite")] + pub web_site: String, + /// The business tax identification number (EIN). + #[serde(rename = "taxIdNumber")] + pub tax_id_number: String, + /// The type of business entity. + #[serde(rename = "entityType")] + pub entity_type: String, + /// The state where the business is incorporated. + #[serde(rename = "stateOfIncorporation")] + pub state_of_incorporation: String, + /// The primary type of business (e.g., Retail, Service, etc.). + #[serde(rename = "merchantType")] + pub merchant_type: String, + /// A short description of the products and services sold. + #[serde(rename = "businessDescription")] + pub business_description: String, + /// The number of years the business has been operating. + #[serde(rename = "yearsInBusiness")] + pub years_in_business: String, + /// The business telephone number. + #[serde(rename = "businessPhoneNumber")] + pub business_phone_number: String, + /// The physical address of the business. + #[serde(rename = "physicalAddress")] + pub physical_address: Address, + /// The mailing address of the business. + #[serde(rename = "mailingAddress")] + pub mailing_address: Address, + /// The first name of the primary contact. + #[serde(rename = "contactFirstName")] + pub contact_first_name: String, + /// The last name of the primary contact. + #[serde(rename = "contactLastName")] + pub contact_last_name: String, + /// The phone number of the primary contact. + #[serde(rename = "contactPhoneNumber")] + pub contact_phone_number: String, + /// The email address of the primary contact. + #[serde(rename = "contactEmail")] + pub contact_email: String, + /// The job title of the primary contact. + #[serde(rename = "contactTitle")] + pub contact_title: String, + /// The tax identification number (SSN) of the primary contact. + #[serde(rename = "contactTaxIdNumber")] + pub contact_tax_id_number: String, + /// The date of birth of the primary contact. + #[serde(rename = "contactDOB")] + pub contact_dob: String, + /// The driver's license number of the primary contact. + #[serde(rename = "contactDlNumber")] + pub contact_dl_number: String, + /// The state that issued the primary contact's driver's license. + #[serde(rename = "contactDlStateOrProvince")] + pub contact_dl_state_or_province: String, + /// The expiration date of the primary contact's driver's license. + #[serde(rename = "contactDlExpiration")] + pub contact_dl_expiration: String, + /// The home address of the primary contact. + #[serde(rename = "contactHomeAddress")] + pub contact_home_address: Address, + /// The role of the primary contact in the business. + #[serde(rename = "contactRole")] + pub contact_role: String, + /// List of individuals with 25% or more ownership in the company. + #[serde(rename = "owners")] + pub owners: Option>, + /// The bank account information for the business. + #[serde(rename = "manualAccount")] + pub manual_account: ApplicationAccount, + /// The average transaction amount. + #[serde(rename = "averageTransaction")] + pub average_transaction: String, + /// The highest expected transaction amount. + #[serde(rename = "highTransaction")] + pub high_transaction: String, + /// The average monthly transaction volume. + #[serde(rename = "averageMonth")] + pub average_month: String, + /// The highest expected monthly transaction volume. + #[serde(rename = "highMonth")] + pub high_month: String, + /// The refund policy of the business. + #[serde(rename = "refundPolicy")] + pub refund_policy: String, + /// The number of days after purchase that refunds can be issued. + #[serde(rename = "refundDays")] + pub refund_days: String, + /// The time zone of the business. + #[serde(rename = "timeZone")] + pub time_zone: String, + /// The time when the daily batch should close. + #[serde(rename = "batchCloseTime")] + pub batch_close_time: String, + /// Indicates if the business has multiple locations. + #[serde(rename = "multipleLocations")] + pub multiple_locations: String, + /// The name of this specific business location. + #[serde(rename = "locationName")] + pub location_name: String, + /// The store number for this location. + #[serde(rename = "storeNumber")] + pub store_number: String, + /// Indicates if the business wants to accept EBT cards. + #[serde(rename = "ebtRequested")] + pub ebt_requested: String, + /// The FNS number issued by the USDA for EBT processing. + #[serde(rename = "fnsNumber")] + pub fns_number: String, + /// Indicates if the business plans to accept payments through a website. + #[serde(rename = "ecommerce")] + pub ecommerce: String, + /// Indicates if suppliers ship products directly to customers. + #[serde(rename = "dropShipping")] + pub drop_shipping: bool, + /// The percentage of transactions that will be chip or swipe. + #[serde(rename = "cardPresentPercentage")] + pub card_present_percentage: String, + /// The percentage of transactions that will be phone orders. + #[serde(rename = "phoneOrderPercentage")] + pub phone_order_percentage: String, + /// The percentage of transactions that will be e-commerce. + #[serde(rename = "ecomPercentage")] + pub ecom_percentage: String, + /// The number of days before shipment that customers are charged. + #[serde(rename = "billBeforeShipmentDays")] + pub bill_before_shipment_days: String, + /// Indicates if the business plans to process recurring payments. + #[serde(rename = "subscriptionsSupported")] + pub subscriptions_supported: String, + /// The frequency of recurring payments (if applicable). + #[serde(rename = "subscriptionFrequency")] + pub subscription_frequency: String, + /// The full legal name of the person signing the application. + #[serde(rename = "signerName")] + pub signer_name: String, + +} + +/// Models a merchant application submission request to add a new merchant account. +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct SubmitApplicationRequest { + /// The request timeout in seconds. + #[serde(rename = "timeout")] + pub timeout: i32, + /// Whether or not to route transaction to the test gateway. + #[serde(rename = "test")] + pub test: bool, + /// The invite code for the merchant. + #[serde(rename = "inviteCode")] + pub invite_code: String, + /// The business name your customers know you by (DBA Name). + #[serde(rename = "dbaName")] + pub dba_name: String, + /// The name of the legal entity you file your taxes under. + #[serde(rename = "corporateName")] + pub corporate_name: String, + /// The business website. + #[serde(rename = "webSite")] + pub web_site: String, + /// The business tax identification number (EIN). + #[serde(rename = "taxIdNumber")] + pub tax_id_number: String, + /// The type of business entity. + #[serde(rename = "entityType")] + pub entity_type: String, + /// The state where the business is incorporated. + #[serde(rename = "stateOfIncorporation")] + pub state_of_incorporation: String, + /// The primary type of business (e.g., Retail, Service, etc.). + #[serde(rename = "merchantType")] + pub merchant_type: String, + /// A short description of the products and services sold. + #[serde(rename = "businessDescription")] + pub business_description: String, + /// The number of years the business has been operating. + #[serde(rename = "yearsInBusiness")] + pub years_in_business: String, + /// The business telephone number. + #[serde(rename = "businessPhoneNumber")] + pub business_phone_number: String, + /// The physical address of the business. + #[serde(rename = "physicalAddress")] + pub physical_address: Address, + /// The mailing address of the business. + #[serde(rename = "mailingAddress")] + pub mailing_address: Address, + /// The first name of the primary contact. + #[serde(rename = "contactFirstName")] + pub contact_first_name: String, + /// The last name of the primary contact. + #[serde(rename = "contactLastName")] + pub contact_last_name: String, + /// The phone number of the primary contact. + #[serde(rename = "contactPhoneNumber")] + pub contact_phone_number: String, + /// The email address of the primary contact. + #[serde(rename = "contactEmail")] + pub contact_email: String, + /// The job title of the primary contact. + #[serde(rename = "contactTitle")] + pub contact_title: String, + /// The tax identification number (SSN) of the primary contact. + #[serde(rename = "contactTaxIdNumber")] + pub contact_tax_id_number: String, + /// The date of birth of the primary contact. + #[serde(rename = "contactDOB")] + pub contact_dob: String, + /// The driver's license number of the primary contact. + #[serde(rename = "contactDlNumber")] + pub contact_dl_number: String, + /// The state that issued the primary contact's driver's license. + #[serde(rename = "contactDlStateOrProvince")] + pub contact_dl_state_or_province: String, + /// The expiration date of the primary contact's driver's license. + #[serde(rename = "contactDlExpiration")] + pub contact_dl_expiration: String, + /// The home address of the primary contact. + #[serde(rename = "contactHomeAddress")] + pub contact_home_address: Address, + /// The role of the primary contact in the business. + #[serde(rename = "contactRole")] + pub contact_role: String, + /// List of individuals with 25% or more ownership in the company. + #[serde(rename = "owners")] + pub owners: Option>, + /// The bank account information for the business. + #[serde(rename = "manualAccount")] + pub manual_account: ApplicationAccount, + /// The average transaction amount. + #[serde(rename = "averageTransaction")] + pub average_transaction: String, + /// The highest expected transaction amount. + #[serde(rename = "highTransaction")] + pub high_transaction: String, + /// The average monthly transaction volume. + #[serde(rename = "averageMonth")] + pub average_month: String, + /// The highest expected monthly transaction volume. + #[serde(rename = "highMonth")] + pub high_month: String, + /// The refund policy of the business. + #[serde(rename = "refundPolicy")] + pub refund_policy: String, + /// The number of days after purchase that refunds can be issued. + #[serde(rename = "refundDays")] + pub refund_days: String, + /// The time zone of the business. + #[serde(rename = "timeZone")] + pub time_zone: String, + /// The time when the daily batch should close. + #[serde(rename = "batchCloseTime")] + pub batch_close_time: String, + /// Indicates if the business has multiple locations. + #[serde(rename = "multipleLocations")] + pub multiple_locations: String, + /// The name of this specific business location. + #[serde(rename = "locationName")] + pub location_name: String, + /// The store number for this location. + #[serde(rename = "storeNumber")] + pub store_number: String, + /// Indicates if the business wants to accept EBT cards. + #[serde(rename = "ebtRequested")] + pub ebt_requested: String, + /// The FNS number issued by the USDA for EBT processing. + #[serde(rename = "fnsNumber")] + pub fns_number: String, + /// Indicates if the business plans to accept payments through a website. + #[serde(rename = "ecommerce")] + pub ecommerce: String, + /// Indicates if suppliers ship products directly to customers. + #[serde(rename = "dropShipping")] + pub drop_shipping: bool, + /// The percentage of transactions that will be chip or swipe. + #[serde(rename = "cardPresentPercentage")] + pub card_present_percentage: String, + /// The percentage of transactions that will be phone orders. + #[serde(rename = "phoneOrderPercentage")] + pub phone_order_percentage: String, + /// The percentage of transactions that will be e-commerce. + #[serde(rename = "ecomPercentage")] + pub ecom_percentage: String, + /// The number of days before shipment that customers are charged. + #[serde(rename = "billBeforeShipmentDays")] + pub bill_before_shipment_days: String, + /// Indicates if the business plans to process recurring payments. + #[serde(rename = "subscriptionsSupported")] + pub subscriptions_supported: String, + /// The frequency of recurring payments (if applicable). + #[serde(rename = "subscriptionFrequency")] + pub subscription_frequency: String, + /// The full legal name of the person signing the application. + #[serde(rename = "signerName")] + pub signer_name: String, + +} + /// A request for customer signature data. diff --git a/tests/submit_application_tests.rs b/tests/submit_application_tests.rs new file mode 100644 index 0000000..b1d3029 --- /dev/null +++ b/tests/submit_application_tests.rs @@ -0,0 +1,123 @@ +// Copyright 2019-2024 BlockChyp, Inc. All rights reserved. Use of this code +// is governed by a license that can be found in the LICENSE file. +// +// This file was generated automatically by the BlockChyp SDK Generator. +// Changes to this file will be lost every time the code is regenerated. + +mod test_utils; +use blockchyp; + +#[test] +fn test_submit_application() { + let config = test_utils::load_test_configuration(); + let client = config.new_test_client(Some("partner")); + + // request object + let request = blockchyp::SubmitApplicationRequest{ + test: true, + invite_code: "asdf".to_string(), + dba_name: "BlockChyp".to_string(), + corporate_name: "BlockChyp Inc.".to_string(), + web_site: "https://www.blockchyp.com".to_string(), + tax_id_number: "123456789".to_string(), + entity_type: "CORPORATION".to_string(), + state_of_incorporation: "UT".to_string(), + merchant_type: "RETAIL".to_string(), + business_description: "Payment processing solutions".to_string(), + years_in_business: "5".to_string(), + business_phone_number: "5555551234".to_string(), + physical_address: blockchyp::Address{ + address_1: "355 S 520 W".to_string(), + city: "Lindon".to_string(), + state_or_province: "UT".to_string(), + postal_code: "84042".to_string(), + country_code: "US".to_string(), + ..Default::default() + }, + mailing_address: blockchyp::Address{ + address_1: "355 S 520 W".to_string(), + city: "Lindon".to_string(), + state_or_province: "UT".to_string(), + postal_code: "84042".to_string(), + country_code: "US".to_string(), + ..Default::default() + }, + contact_first_name: "John".to_string(), + contact_last_name: "Doe".to_string(), + contact_phone_number: "5555555678".to_string(), + contact_email: "john.doe@example.com".to_string(), + contact_title: "CEO".to_string(), + contact_tax_id_number: "987654321".to_string(), + contact_dob: "1980-01-01".to_string(), + contact_dl_number: "D1234567".to_string(), + contact_dl_state_or_province: "NY".to_string(), + contact_dl_expiration: "2025-12-31".to_string(), + contact_home_address: blockchyp::Address{ + address_1: "355 S 520 W".to_string(), + city: "Lindon".to_string(), + state_or_province: "UT".to_string(), + postal_code: "84042".to_string(), + country_code: "US".to_string(), + ..Default::default() + }, + contact_role: "OWNER".to_string(), + owners: Some(vec![ + blockchyp::Owner{ + first_name: "John".to_string(), + last_name: "Doe".to_string(), + job_title: "CEO".to_string(), + tax_id_number: "876543210".to_string(), + phone_number: "5555559876".to_string(), + dob: "1981-02-02".to_string(), + ownership: "50".to_string(), + email: "john.doe@example.com".to_string(), + dl_number: "D7654321".to_string(), + dl_state_or_province: "UT".to_string(), + dl_expiration: "2024-12-31".to_string(), + address: blockchyp::Address{ + address_1: "355 S 520 W".to_string(), + city: "Lindon".to_string(), + state_or_province: "UT".to_string(), + postal_code: "84042".to_string(), + country_code: "US".to_string(), + ..Default::default() + }, + ..Default::default() + }, + + ]), + manual_account: blockchyp::ApplicationAccount{ + name: "Business Checking".to_string(), + bank: "Test Bank".to_string(), + account_holder_name: "BlockChyp Inc.".to_string(), + routing_number: "124001545".to_string(), + account_number: "987654321".to_string(), + ..Default::default() + }, + average_transaction: "100.00".to_string(), + high_transaction: "1000.00".to_string(), + average_month: "10000.00".to_string(), + high_month: "20000.00".to_string(), + refund_policy: "30_DAYS".to_string(), + refund_days: "30".to_string(), + time_zone: "America/Denver".to_string(), + batch_close_time: "23:59".to_string(), + multiple_locations: "false".to_string(), + ebt_requested: "false".to_string(), + ecommerce: "true".to_string(), + card_present_percentage: "70".to_string(), + phone_order_percentage: "10".to_string(), + ecom_percentage: "20".to_string(), + signer_name: "John Doe".to_string(), + ..Default::default() + }; + println!("Request: {:?}", request); + + let (response, err) = client.submit_application(&request); + assert!(err.is_none(), "err is not none: {:?}", err); + + println!("Response: {:?}", response); + + // response assertions + assert!(response.success); +}