A quick article on some code added to a button in ZohoBooks off the invoice module to initiate your Stripe terminal to take a payment.
Why?
Just to make it easy on the staff at a counter or on the phone. They bring up the invoie in ZohoBooks, click on the button, and the Stripe terminal will ask for the amount on the invoice.
Well almost. We've gone the extra step in that we added a custom field that can override the full balance, to allow partial payments such as a deposit or instalment.
How?
I won't go in to how to create a button in ZohoBooks but you simply add it to the invoice and then when it prompts for some code, you give it the snippet below.
The Magic
You would create a button for each terminal
copyraw
	
/* *******************************************************************************
Function:       Map Take_Payment( Map invoice, Map organization, Map user)
Label:          Take Payment
Trigger:        On button click
Purpose:		Preps stripe terminal to take payment for balance of invoice.
Inputs:         invoice
Outputs:        -
Date Created:   2023-02-24 
                - Initial release
				- Reads Books Invoice and sends the amount to the reader for a payment atempt
Date Modified:	2023-02-24 (Joel Lipman)
                - If custom field "Amount To Be Taken" is not greater than zero, then defaults to balance due of invoice.
More Information:
		TEST PAYMENT SCENARIOS WITH PHYSICAL TEST CARD 
		// Send in as payment endings: eg. $100.00 == payment approved
		00 Payment Approved
		01 Payment Declined // call issuer code
		05 Payment Declined Generic
		55 Payment Declined Incorrect Pin
		65 Payment Declined withdrawal_count_limit_exceeded
		75 Pin try exceeded
******************************************************************************* */
v_BooksOrgID = organization.get("organization_id");
//
// some Stripe variables (add your own here)
v_StripeTerminalID = "tmr_ABCDEFGabcdefg";
v_StripeCustomerKey = "sk_live_1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
V_StripeLocationsEndpoint = " https://api.stripe.com/v1/terminal/locations";
//
// set Stripe header
m_Headers = Map();
m_Headers.put("Authorization","Bearer " + v_StripeCustomerKey);
//
// default to balance due on this Invoice
v_AmountToPay = ifnull(invoice.get("balance"),0);
//
// Get custom Amount to Pay from Invoice
l_CustomFields = invoice.get("custom_fields");
if(l_CustomFields.size() > 0)
{
	for each  m_CustomField in l_CustomFields
	{
		if(m_CustomField.get("label") == "Amount To Be Taken")
		{
			if(m_CustomField.get("value") > 0)
			{
				v_AmountToPay = m_CustomField.get("value");
			}
		}
	}
}
//
// format to Stripe amount
v_AmountToPay = v_AmountToPay.truncate(2);
v_StripeAmount = v_AmountToPay * 100;
v_StripeAmount = v_StripeAmount.floor();
v_StripeAmount = v_StripeAmount.toNumber();
info v_StripeAmount;
//
// Create payment intent in Stripe
v_PaymentIntentEndpoint = "https://api.stripe.com/v1/payment_intents";
m_Params = Map();
m_Params.put("amount",v_StripeAmount);
m_Params.put("currency","gbp");
//m_Params.put("automatic_payment_methods[enabled]", false);
m_Params.put("payment_method_types[]","card_present");
m_Params.put("capture_method","manual");
v_DescriptionString = "IN: " + invoice.get("invoice_number") + " ID: " + invoice.get("invoice_id");
m_Params.put("description",v_DescriptionString);
// Later Add Code to  "customer_id": "123456700000001234567", get customer id then Email
v_BooksCustomerID = invoice.get("customer_id");
r_CustomerDetails = zoho.books.getRecordsByID("contacts",v_BooksOrgID,v_BooksCustomerID,"zbooks");
v_CustomerCheckCode = r_CustomerDetails.get("code");
if(v_CustomerCheckCode == 0)
{
	m_ContactDetails = r_CustomerDetails.get("contact");
	if(m_ContactDetails != null)
	{
		m_Params.put("receipt_email",m_ContactDetails.get("email"));
	}
}
r_CreatePaymentIntent = invokeurl
[
	url :v_PaymentIntentEndpoint
	type :POST
	parameters:m_Params
	headers:m_Headers
];
info "Payment Intent Create";
info r_CreatePaymentIntent;
//
v_CheckObject = ifnull(r_CreatePaymentIntent.get("object"),"-");
v_CheckAmount = ifnull(r_CreatePaymentIntent.get("amount"),"-");
//
// Process Payment Intent
if(v_CheckObject == "payment_intent")
{
	v_PaymentIntentID = r_CreatePaymentIntent.get("id");
	info "Payment Intent Created Successfuly!!! ID: ";
	info v_PaymentIntentID;
	//
	// Hand Off Payment Intent to Reader
	v_ReaderHandOffEndpoint = "https://api.stripe.com/v1/terminal/readers/" + v_StripeTerminalID + "/process_payment_intent";
	m_PaymentHandOffParams = Map();
	m_PaymentHandOffParams.put("payment_intent",v_PaymentIntentID);
	r_ReaderPaymentHandOff = invokeurl
	[
		url :v_ReaderHandOffEndpoint
		type :POST
		parameters:m_PaymentHandOffParams
		headers:m_Headers
	];
	info r_ReaderPaymentHandOff;
}
return r_ReaderPaymentHandOff;
	- /* *******************************************************************************
- Function: Map Take_Payment( Map invoice, Map organization, Map user)
- Label: Take Payment
- Trigger: On button click
- Purpose: Preps stripe terminal to take payment for balance of invoice.
- Inputs: invoice
- Outputs: -
- Date Created: 2023-02-24
- - Initial release
- - Reads Books Invoice and sends the amount to the reader for a payment atempt
- Date Modified: 2023-02-24 (Joel Lipman)
- - If custom field "Amount To Be Taken" is not greater than zero, then defaults to balance due of invoice.
- More Information:
- TEST PAYMENT SCENARIOS WITH PHYSICAL TEST CARD
- // Send in as payment endings: eg. $100.00 == payment approved
- 00 Payment Approved
- 01 Payment Declined // call issuer code
- 05 Payment Declined Generic
- 55 Payment Declined Incorrect Pin
- 65 Payment Declined withdrawal_count_limit_exceeded
- 75 Pin try exceeded
- ******************************************************************************* */
- v_BooksOrgID = organization.get("organization_id");
- //
- // some Stripe variables (add your own here)
- v_StripeTerminalID = "tmr_ABCDEFGabcdefg";
- v_StripeCustomerKey = "sk_live_1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- V_StripeLocationsEndpoint = " https://api.stripe.com/v1/terminal/locations";
- //
- // set Stripe header
- m_Headers = Map();
- m_Headers.put("Authorization","Bearer " + v_StripeCustomerKey);
- //
- // default to balance due on this Invoice
- v_AmountToPay = ifnull(invoice.get("balance"),0);
- //
- // Get custom Amount to Pay from Invoice
- l_CustomFields = invoice.get("custom_fields");
- if(l_CustomFields.size() > 0)
- {
- for each m_CustomField in l_CustomFields
- {
- if(m_CustomField.get("label") == "Amount To Be Taken")
- {
- if(m_CustomField.get("value") > 0)
- {
- v_AmountToPay = m_CustomField.get("value");
- }
- }
- }
- }
- //
- // format to Stripe amount
- v_AmountToPay = v_AmountToPay.truncate(2);
- v_StripeAmount = v_AmountToPay * 100;
- v_StripeAmount = v_StripeAmount.floor();
- v_StripeAmount = v_StripeAmount.toNumber();
- info v_StripeAmount;
- //
- // Create payment intent in Stripe
- v_PaymentIntentEndpoint = "https://api.stripe.com/v1/payment_intents";
- m_Params = Map();
- m_Params.put("amount",v_StripeAmount);
- m_Params.put("currency","gbp");
- //m_Params.put("automatic_payment_methods[enabled]", false);
- m_Params.put("payment_method_types[]","card_present");
- m_Params.put("capture_method","manual");
- v_DescriptionString = "IN: " + invoice.get("invoice_number") + " ID: " + invoice.get("invoice_id");
- m_Params.put("description",v_DescriptionString);
- // Later Add Code to "customer_id": "123456700000001234567", get customer id then Email
- v_BooksCustomerID = invoice.get("customer_id");
- r_CustomerDetails = zoho.books.getRecordsByID("contacts",v_BooksOrgID,v_BooksCustomerID,"zbooks");
- v_CustomerCheckCode = r_CustomerDetails.get("code");
- if(v_CustomerCheckCode == 0)
- {
- m_ContactDetails = r_CustomerDetails.get("contact");
- if(m_ContactDetails != null)
- {
- m_Params.put("receipt_email",m_ContactDetails.get("email"));
- }
- }
- r_CreatePaymentIntent = invokeUrl
- [
- url :v_PaymentIntentEndpoint
- type :POST
- parameters:m_Params
- headers:m_Headers
- ];
- info "Payment Intent Create";
- info r_CreatePaymentIntent;
- //
- v_CheckObject = ifnull(r_CreatePaymentIntent.get("object"),"-");
- v_CheckAmount = ifnull(r_CreatePaymentIntent.get("amount"),"-");
- //
- // Process Payment Intent
- if(v_CheckObject == "payment_intent")
- {
- v_PaymentIntentID = r_CreatePaymentIntent.get("id");
- info "Payment Intent Created Successfuly!!! ID: ";
- info v_PaymentIntentID;
- //
- // Hand Off Payment Intent to Reader
- v_ReaderHandOffEndpoint = "https://api.stripe.com/v1/terminal/readers/" + v_StripeTerminalID + "/process_payment_intent";
- m_PaymentHandOffParams = Map();
- m_PaymentHandOffParams.put("payment_intent",v_PaymentIntentID);
- r_ReaderPaymentHandOff = invokeUrl
- [
- url :v_ReaderHandOffEndpoint
- type :POST
- parameters:m_PaymentHandOffParams
- headers:m_Headers
- ];
- info r_ReaderPaymentHandOff;
- }
- return r_ReaderPaymentHandOff;
The incoming webhook
You now need to receive the Stripe webhook when it comes back into ZohoBooks to record it against the invoice. Note how we added the invoice reference and Zoho ID in the description of the payment capture in our previous bit of code:
copyraw
	
/* *******************************************************************************
Function:       Map stripe_terminal_payment( Map invoice, Map organization, Map user)
Label:          stripe_terminal_payment
Trigger:        Incoming Webhook
Purpose:		Listens for stripe terminal payments.
OAuth URL:		https://www.zohoapis.com/books/v3/settings/incomingwebhooks/iw_stripe_terminal_payment/execute?auth_type=oauth
Inputs:         invoice
Outputs:        -
Date Created:   2023-03-23 
                - Initial release
				- been successfully proccessed by the physical reader
Date Modified:	2024-05-21 (Joel Lipman)
                - Revamp of code as per best practices
                - Correct error: Check and update the code in line 74 as there is a Exception : Value is empty and 'get' function cannot be applied
More Information:
		Navigate to payments, then find pending webhook response event, terminal.reader.action_succeeded, then view event details
******************************************************************************* */
//
// initialize
m_Blank = Map();
m_Response = Map();
v_BooksOrgID = organization.get("organization_id");
//
// Stripe API Key (add your own here)
v_StripeCustomerKey = "sk_live_1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//
// set Stripe header
m_Headers = Map();
m_Headers.put("Authorization","Bearer " + v_StripeCustomerKey);
//
// capture response webhook
m_Webhook = Map();
m_Webhook.put("data",body.get("data"));
m_Webhook.put("type",body.get("type"));
//
// Check Type 
m_Data = ifnull(m_Webhook.get("data"),m_Blank);
v_Type = ifnull(m_Webhook.get("type"),"-");
if(v_Type == "terminal.reader.action_succeeded")
{
	// Get Payment Intent that needs to be Captured
	m_Object = m_Data.get("object");
	m_Action = m_Object.get("action");
	m_ProcessPaymentIntent = m_Action.get("process_payment_intent");
	v_PaymentIntentID = m_ProcessPaymentIntent.get("payment_intent");
	//
	// Retrieve details on the Payment Intent
	v_PaymentIntentEndpoint = "https://api.stripe.com/v1/payment_intents/" + v_PaymentIntentID;
	r_PaymentIntentDetails = invokeurl
	[
		url :v_PaymentIntentEndpoint
		type :GET
		headers:m_Headers
	];
	//
	// get amount (used to capture payment intent)
	v_Amount = ifnull(r_PaymentIntentDetails.get("amount"),0);
	v_AmountReceived = ifnull(r_PaymentIntentDetails.get("amount_received"),0);
	v_AmountCapturable = ifnull(r_PaymentIntentDetails.get("amount_capturable"),0);
	v_CaptureIntentEndpoint = "https://api.stripe.com/v1/payment_intents/" + v_PaymentIntentID + "/capture";
	m_CaptureParams = Map();
	m_CaptureParams.put("amount_to_capture",v_AmountCapturable);
	r_CapturePayment = invokeurl
	[
		url :v_CaptureIntentEndpoint
		type :POST
		parameters:m_CaptureParams
		headers:m_Headers
	];
	//
	// get card details (we need to store last 4 digits)
	v_StripeReference = "";
	v_Last4Digits = "";
	v_ZB_InvoiceID = 0;
	m_Charges = ifnull(r_PaymentIntentDetails.get("charges"),m_Blank);
	l_Data = ifnull(m_Charges.get("data"),{});
	for each  m_Data in l_Data
	{
		if(m_Data.get("id") != null)
		{
			v_StripeReference = m_Data.get("id");
		}
		if(m_Data.get("payment_method_details") != null)
		{
			m_CardPresent = ifnull(m_Data.get("payment_method_details").get("card_present"),m_Blank);
			v_Last4Digits = ifnull(m_CardPresent.get("last4"),"");
		}
		if(m_Data.get("description") != null)
		{
			v_ChargeDescription = ifnull(m_Data.get("description"),"");
			v_ZB_InvoiceID = v_ChargeDescription.getSuffix("ID: ");
			v_ZB_InvoiceID = if(isNumber(v_ZB_InvoiceID),v_ZB_InvoiceID,0).toLong();
		}
	}
	//
	// create payment record
	if(v_ZB_InvoiceID != 0)
	{
		//
		// get ZohoBooks nominal account for Stripe
		v_NominalAccountID = "";
		r_ChartOfAccounts = invokeurl
		[
			url :"https://www.zohoapis.com/books/v3/chartofaccounts?organization_id=" + v_BooksOrgID
			type :GET
			connection:"zbooks"
		];
		if(r_ChartOfAccounts.get("chartofaccounts") != null)
		{
			for each  m_NomAccount in r_ChartOfAccounts.get("chartofaccounts")
			{
				if(m_NomAccount.get("account_name").equalsIgnoreCase("Stripe Clearing"))
				{
					v_NominalAccountID = m_NomAccount.get("account_id");
				}
			}
		}
		//
		// retrieve invoice details from ZohoBooks
		r_InvoiceDetails = zoho.books.getRecordsByID("invoices",v_BooksOrgID,v_ZB_InvoiceID,"zbooks");
		m_Invoice = ifnull(r_InvoiceDetails.get("invoice"),m_Blank);
		if(m_Invoice.get("customer_id") != null)
		{
			m_CreatePayment = Map();
			m_CreatePayment.put("customer_id",m_Invoice.get("customer_id"));
			m_CreatePayment.put("payment_mode","In Person - Card");
			m_CreatePayment.put("amount",v_AmountReceived / 100);
			m_CreatePayment.put("date",zoho.currentdate.toString("yyyy-MM-dd"));
			//
			l_Invoices = List();
			m_ThisInvoice = Map();
			m_ThisInvoice.put("invoice_id",v_ZB_InvoiceID.toString());
			m_ThisInvoice.put("amount_applied",v_AmountReceived / 100);
			l_Invoices.add(m_ThisInvoice);
			m_CreatePayment.put("invoices",l_Invoices);
			m_CreatePayment.put("invoice_id",v_ZB_InvoiceID.toString());
			m_CreatePayment.put("amount_applied",v_AmountReceived / 100);
			//
			v_PaymentRef = if(v_StripeReference=="", m_Invoice.get("invoice_number"), v_StripeReference);
			m_CreatePayment.put("reference_number",v_PaymentRef);
			m_CreatePayment.put("account_id",v_NominalAccountID);
			//info m_CreatePayment;
			//
			r_CreatePayment = zoho.books.createRecord("customerpayments",v_BooksOrgID,m_CreatePayment,"zbooks");
			//info r_CreatePayment;
			if(r_CreatePayment.get("message") != null)
			{
				if(r_CreatePayment.get("message").contains("payment has been created"))
				{
					//
					// update the invoice (request by client to store last 4 digits on invoice)
					l_CustomFields = List();
					m_CustomField = Map();
					m_CustomField.put("api_name","cf_last_4_digits");
					m_CustomField.put("value",v_Last4Digits);
					l_CustomFields.add(m_CustomField);
					m_UpdateInvoice = Map();
					m_UpdateInvoice.put("custom_fields",l_CustomFields);
					r_UpdateInvoice = zoho.books.updateRecord("Invoices",v_BooksOrgID,v_ZB_InvoiceID,m_UpdateInvoice,"zbooks");
				}
			}
		}
	}
}
m_Response.put("message",r_CreatePayment.get("message"));
m_Response.put("code",0);
return m_Response;
	- /* *******************************************************************************
- Function: Map stripe_terminal_payment( Map invoice, Map organization, Map user)
- Label: stripe_terminal_payment
- Trigger: Incoming Webhook
- Purpose: Listens for stripe terminal payments.
- OAuth url: https://www.zohoapis.com/books/v3/settings/incomingwebhooks/iw_stripe_terminal_payment/execute?auth_type=oauth
- Inputs: invoice
- Outputs: -
- Date Created: 2023-03-23
- - Initial release
- - been successfully proccessed by the physical reader
- Date Modified: 2024-05-21 (Joel Lipman)
- - Revamp of code as per best practices
- - Correct error: Check and update the code in line 74 as there is a Exception : Value is empty and 'get' function cannot be applied
- More Information:
- Navigate to payments, then find pending webhook response event, terminal.reader.action_succeeded, then view event details
- ******************************************************************************* */
- //
- // initialize
- m_Blank = Map();
- m_Response = Map();
- v_BooksOrgID = organization.get("organization_id");
- //
- // Stripe API Key (add your own here)
- v_StripeCustomerKey = "sk_live_1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- //
- // set Stripe header
- m_Headers = Map();
- m_Headers.put("Authorization","Bearer " + v_StripeCustomerKey);
- //
- // capture response webhook
- m_Webhook = Map();
- m_Webhook.put("data",body.get("data"));
- m_Webhook.put("type",body.get("type"));
- //
- // Check Type
- m_Data = ifnull(m_Webhook.get("data"),m_Blank);
- v_Type = ifnull(m_Webhook.get("type"),"-");
- if(v_Type == "terminal.reader.action_succeeded")
- {
- // Get Payment Intent that needs to be Captured
- m_Object = m_Data.get("object");
- m_Action = m_Object.get("action");
- m_ProcessPaymentIntent = m_Action.get("process_payment_intent");
- v_PaymentIntentID = m_ProcessPaymentIntent.get("payment_intent");
- //
- // Retrieve details on the Payment Intent
- v_PaymentIntentEndpoint = "https://api.stripe.com/v1/payment_intents/" + v_PaymentIntentID;
- r_PaymentIntentDetails = invokeUrl
- [
- url :v_PaymentIntentEndpoint
- type :GET
- headers:m_Headers
- ];
- //
- // get amount (used to capture payment intent)
- v_Amount = ifnull(r_PaymentIntentDetails.get("amount"),0);
- v_AmountReceived = ifnull(r_PaymentIntentDetails.get("amount_received"),0);
- v_AmountCapturable = ifnull(r_PaymentIntentDetails.get("amount_capturable"),0);
- v_CaptureIntentEndpoint = "https://api.stripe.com/v1/payment_intents/" + v_PaymentIntentID + "/capture";
- m_CaptureParams = Map();
- m_CaptureParams.put("amount_to_capture",v_AmountCapturable);
- r_CapturePayment = invokeUrl
- [
- url :v_CaptureIntentEndpoint
- type :POST
- parameters:m_CaptureParams
- headers:m_Headers
- ];
- //
- // get card details (we need to store last 4 digits)
- v_StripeReference = "";
- v_Last4Digits = "";
- v_ZB_InvoiceID = 0;
- m_Charges = ifnull(r_PaymentIntentDetails.get("charges"),m_Blank);
- l_Data = ifnull(m_Charges.get("data"),{});
- for each m_Data in l_Data
- {
- if(m_Data.get("id") != null)
- {
- v_StripeReference = m_Data.get("id");
- }
- if(m_Data.get("payment_method_details") != null)
- {
- m_CardPresent = ifnull(m_Data.get("payment_method_details").get("card_present"),m_Blank);
- v_Last4Digits = ifnull(m_CardPresent.get("last4"),"");
- }
- if(m_Data.get("description") != null)
- {
- v_ChargeDescription = ifnull(m_Data.get("description"),"");
- v_ZB_InvoiceID = v_ChargeDescription.getSuffix("ID: ");
- v_ZB_InvoiceID = if(isNumber(v_ZB_InvoiceID),v_ZB_InvoiceID,0).toLong();
- }
- }
- //
- // create payment record
- if(v_ZB_InvoiceID != 0)
- {
- //
- // get ZohoBooks nominal account for Stripe
- v_NominalAccountID = "";
- r_ChartOfAccounts = invokeUrl
- [
- url :"https://www.zohoapis.com/books/v3/chartofaccounts?organization_id=" + v_BooksOrgID
- type :GET
- connection:"zbooks"
- ];
- if(r_ChartOfAccounts.get("chartofaccounts") != null)
- {
- for each m_NomAccount in r_ChartOfAccounts.get("chartofaccounts")
- {
- if(m_NomAccount.get("account_name").equalsIgnoreCase("Stripe clearing"))
- {
- v_NominalAccountID = m_NomAccount.get("account_id");
- }
- }
- }
- //
- // retrieve invoice details from ZohoBooks
- r_InvoiceDetails = zoho.books.getRecordsByID("invoices",v_BooksOrgID,v_ZB_InvoiceID,"zbooks");
- m_Invoice = ifnull(r_InvoiceDetails.get("invoice"),m_Blank);
- if(m_Invoice.get("customer_id") != null)
- {
- m_CreatePayment = Map();
- m_CreatePayment.put("customer_id",m_Invoice.get("customer_id"));
- m_CreatePayment.put("payment_mode","In Person - Card");
- m_CreatePayment.put("amount",v_AmountReceived / 100);
- m_CreatePayment.put("date",zoho.currentdate.toString("yyyy-MM-dd"));
- //
- l_Invoices = List();
- m_ThisInvoice = Map();
- m_ThisInvoice.put("invoice_id",v_ZB_InvoiceID.toString());
- m_ThisInvoice.put("amount_applied",v_AmountReceived / 100);
- l_Invoices.add(m_ThisInvoice);
- m_CreatePayment.put("invoices",l_Invoices);
- m_CreatePayment.put("invoice_id",v_ZB_InvoiceID.toString());
- m_CreatePayment.put("amount_applied",v_AmountReceived / 100);
- //
- v_PaymentRef = if(v_StripeReference=="", m_Invoice.get("invoice_number"), v_StripeReference);
- m_CreatePayment.put("reference_number",v_PaymentRef);
- m_CreatePayment.put("account_id",v_NominalAccountID);
- //info m_CreatePayment;
- //
- r_CreatePayment = zoho.books.createRecord("customerpayments",v_BooksOrgID,m_CreatePayment,"zbooks");
- //info r_CreatePayment;
- if(r_CreatePayment.get("message") != null)
- {
- if(r_CreatePayment.get("message").contains("payment has been created"))
- {
- //
- // update the invoice (request by client to store last 4 digits on invoice)
- l_CustomFields = List();
- m_CustomField = Map();
- m_CustomField.put("api_name","cf_last_4_digits");
- m_CustomField.put("value",v_Last4Digits);
- l_CustomFields.add(m_CustomField);
- m_UpdateInvoice = Map();
- m_UpdateInvoice.put("custom_fields",l_CustomFields);
- r_UpdateInvoice = zoho.books.updateRecord("Invoices",v_BooksOrgID,v_ZB_InvoiceID,m_UpdateInvoice,"zbooks");
- }
- }
- }
- }
- }
- m_Response.put("message",r_CreatePayment.get("message"));
- m_Response.put("code",0);
- return m_Response;
Source(s):
- Stripe Dashboard - Developers - API Keys
- Stripe Docs - Decline codes - Learn about decline codes and how to resolve them when a charge fails.
Category: Zoho :: Article: 841
	

 
			      
						  
                 
						  
                 
						  
                 
						  
                 
						  
                 
 
 

 
 
Add comment