How to implement Payment SDK
Algorithms
There are five algorithms you must create
initialize_payment
- Create an algorithm called initialize_payment with a parameter called params
- Write your code in the code block
There are three main components you need to make the algorithm work.
- Settings object
- Payment object
- Response method
Tenant.notify(message: "Initialize Example payment", type: :info)
Tenant.notify(message: "#{params}", type: :info)
# params will contain fields
# - payment = Payment object
# get settings from the Settings datatype
setting = get_setting("EXAMPLE_SETTINGS")
# get Payment object for transaction
payment = params["payment"]
# print to the notification log
Tenant.notify(message: "Payment #{payment.to_hash}", type: :info)
# Example of how to use a template as the response
{
"action" => "render",
"template" => "Example::Example Payment Page",
"data" => {
"referenceId" => payment["referenceId"],
"transId" => SecureRandom.uuid(),
"amount" => payment["transactionData"]["amount"]
}
}
# Example of how to send data to user page
#{
# "action" => "return",
# "data" => page
#}
# Example of how to redirect to another site
#{
# "action" => "redirect",
# "redirect_to" => "http://urltohostedpayments"
# } a. Get Settings object - To retrieve the record from the Settings datatype, call the get_setting algorithm
and pass the name of the record
setting = get_setting("EXAMPLE_SETTINGS") b. Get Payment object - retrieve the Payment object that is sent to the algorithm through
params
payment = params["payment"] c. Response method - There are three options for a response method:
- Render a template
{
"action" => "render",
"template" => "Example::Example Payment Page",
"data" => {
"referenceId" => payment["referenceId"],
"transId" => SecureRandom.uuid(),
"amount" => payment["transactionData"]["amount"]
}
} - Send data to user page
{
"action" => "return",
"data" => page
} - Redirect to another site
{
"action" => "redirect",
"redirect_to" => "http://urltohostedpayments"
}- Save the algorithm once completed.
process_payment
- Create an algorithm called process_payment with a parameter called params
- Write your code in the code block
Tenant.notify(message: "Process Example process_payment", type: :info)
Tenant.notify(message: "#{params}", type: :info)
begin
# lookup the Payment entry by referenceId
payment = get_payment(params["referenceId"])
if payment.nil?
Cenit.fail("No Payment entry found for referenceId #{params["referenceId"]}")
end
# Check if the current status is Pending Payment and apply payment if so
if payment["transactionStatus"].casecmp?("Pending Payment")
# update the transactionStatus to either Approved or Failed
status = ""
if params["status"].eql?("APR")
status = "Approved"
end
payment["transactionStatus"] = status
# update the transactionId with the response from the payment provider
payment["transactionId"] = params["transId"]
# save any parameters sent back from the payment provider for later use
payment["transactionData"] = params
# add the payment provider transaction id as the transactionData.referenceId
payment["transactionData"]["referenceId"] = params["transId"]
# set the transactionData.payee to the info returned from the payment provider
payment["transactionData"]["payee"] = "#{params["payeeFirstname"]} #{params["payeeLastname"]}"
# set the transactionData.payee to the info returned from the payment provider
payment["transactionData"]["payeeAddress"] = "#{params["payeeAddress"]}"
# optionally build a URL to the paymnet providers detail page
payment["transactionData"]["detailURL"] = "https://paymentprovider/detail"
# set the transactionData.type
payment["transactionData"]["type"] = "Credit Card"
# payment["transactionData"]["type"] = "Check"
# optionally set the convenience or service fee charged by the payment provder
#payment["transactionData"]["convFee"] = 0
# save the payment
payment = save_payment(payment)
# return a success message as required by the payment provider
#{
# "action"=> "return",
# "code"=> "200",
# "data"=> "Payment completed successfully"
#}
# redirect to transactionData.redirectURL which
# will exist on the Payment after calling save_payment with the
# transactionStatus of Approved or Failed
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
elsif payment["transactionStatus"].casecmp?("Approved") || payment["transactionStatus"].casecmp?("Failed")
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
else
{
"action"=> "return",
"code"=> "500",
"data"=> "Payment in invalid state of #{payment["transactionStatus"]} for further actions"
}
end
rescue StandardError => ex
code = ex.message =~ /^\[(\d+)\]/ ? $1.to_i : 500
message = ex.message.gsub(/^\[(\d+)\] - /, '')
{
"action"=> "return",
"code"=> code,
"data"=> message
}
end a. Lookup Payment record
- Begin the algorithm by looking up the Payment record by the referenceId
payment = get_payment(params["referenceId"]) - Add an if statement to check if the response from get_payment is null and to end the execution if it is
if payment.nil?
Cenit.fail("No Payment entry found for referenceId #{params["referenceId"]}")
end b. Check if current status is Pending
- Check if the current status is Pending Payment and apply payment if so
if payment["transactionStatus"].casecmp?("Pending Payment") - Update the transactionStatus to either Approved or Failed
status = ""
if params["status"].eql?("APR")
status = "Approved"
end
payment["transactionStatus"] = status - Update the transactionId with the response from the payment provider
payment["transactionId"] = params["transId"] - Save any parameters sent back from the payment provider for later use
payment["transactionData"] = params - Add the payment provider transaction id as the transactionData.referenceId
payment["transactionData"]["referenceId"] = params["transId"] - Set the transactionData.payee to the info returned from the payment provider
payment["transactionData"]["payee"] = "#{params["payeeFirstname"]} #{params["payeeLastname"]}" - Set the transactionData.payeeAddress to the info returned from the payment provider
payment["transactionData"]["payeeAddress"] = "#{params["payeeAddress"]}" - Optionally build a URL to the payment providers detail page
payment["transactionData"]["detailURL"] = "https://paymentprovider/detail" - Set the transactionData.type
payment["transactionData"]["type"] = "Credit Card"
OR
payment["transactionData"]["type"] = "Check" - Optionally set the convenience or service fee charged by the payment provder
payment["transactionData"]["convFee"] = 0 - Save the payment
payment = save_payment(payment) c. Redirect to transactionData.redirectURL which will exist on the Payment after calling save_payment with the transactionStatus of Approved or Failed
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
elsif payment["transactionStatus"].casecmp?("Approved") || payment["transactionStatus"].casecmp?("Failed")
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
else
{
"action"=> "return",
"code"=> "500",
"data"=> "Payment in invalid state of #{payment["transactionStatus"]} for further actions"
}
end d. Ending code
rescue StandardError => ex
code = ex.message =~ /^\[(\d+)\]/ ? $1.to_i : 500
message = ex.message.gsub(/^\[(\d+)\] - /, '')
{
"action"=> "return",
"code"=> code,
"data"=> message
}
endpayment_confirmation
- Create an algorithm called payment_confirmation with a parameter called params
- Write your code in the code block
Tenant.notify(message: "Process Example payment_confirmation", type: :info)
Tenant.notify(message: "#{params}", type: :info)
begin
# lookup the Payment entry by referenceId
payment = get_payment(params["referenceId"])
if payment.nil?
Cenit.fail("No Payment entry found for referenceId #{params["referenceId"]}")
end
# Check if the Payment is Approved or Failed and redirect
if payment["transactionStatus"].casecmp?("Approved") || payment["transactionStatus"].casecmp?("Failed")
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
else
{
"action"=> "return",
"code"=> "500",
"data"=> "Payment in invalid state of #{payment["transactionStatus"]} for further actions"
}
end
rescue StandardError => ex
code = ex.message =~ /^\[(\d+)\]/ ? $1.to_i : 500
message = ex.message.gsub(/^\[(\d+)\] - /, '')
{
"action"=> "return",
"code"=> code,
"data"=> message
}
end a. Similarly to the process_payment algorithm, begin payment_confirmation by looking up the Payment record by referenceId and check if it is null
payment = get_payment(params["referenceId"])
if payment.nil?
Cenit.fail("No Payment entry found for referenceId #{params["referenceId"]}")
end b. Check if the Payment status is Approved or Failed and redirect
if payment["transactionStatus"].casecmp?("Approved") || payment["transactionStatus"].casecmp?("Failed")
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
else
{
"action"=> "return",
"code"=> "500",
"data"=> "Payment in invalid state of #{payment["transactionStatus"]} for further actions"
}
end c. End code
rescue StandardError => ex
code = ex.message =~ /^\[(\d+)\]/ ? $1.to_i : 500
message = ex.message.gsub(/^\[(\d+)\] - /, '')
{
"action"=> "return",
"code"=> code,
"data"=> message
}
end- Save algorithm once completed.
cancel_payment
- Create an algorithm called cancel_payment with a parameter called params
- Write your code in the code block
Tenant.notify(message: "Process Example cancel_payment", type: :info)
Tenant.notify(message: "#{params}", type: :info)
payment = get_payment(params["referenceId"])
if payment.nil?
Cenit.fail("No Payment entry found for referenceId #{params["referenceId"]}")
end
payment["transactionStatus"] = "Cancel"
payment["transactionId"] = params["SECURETOKENID"]
payment["transactionData"] = params
payment = save_payment(payment)
if payment["transactionData"]["redirectURL"]
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
else
{
"action"=> "return",
"code"=> "200",
"data"=> "Payment cancelled"
}
end a. Lookup Payment record by reference Id and check if it is null or not
payment = get_payment(params["referenceId"])
if payment.nil?
Cenit.fail("No Payment entry found for referenceId #{params["referenceId"]}")
end b. Set Payment record details and save Payment
payment["transactionStatus"] = "Cancel"
payment["transactionId"] = params["SECURETOKENID"]
payment["transactionData"] = params
payment = save_payment(payment) c. Set redirect
if payment["transactionData"]["redirectURL"]
{
"action" => "redirect",
"redirect_to" => payment["transactionData"]["redirectURL"]
}
else
{
"action"=> "return",
"code"=> "200",
"data"=> "Payment cancelled"
}
end- Save algorithm
Using the SDK
- Go to laserfiche.velosimo.com and login
- Open your forms Process Designer Diagram and show details
- Select start in the diagram and the On Event Completion tab
- Set redirect to website and the URL to the initialize_payment algorithm on the Velosimo site.
Example - https://dev.velosimo.io/app/payment_adapter/laserfiche/example/initialize_payment
payment_adapter = Velosimo tenant
example = Velosimo namespace
initialize_payment = Algorithm
- Submit a new form. Once submitted you will be redirected to an environment where you can test each algorithm created.
a. Click Simulate Approved Postback

Updated 10 months ago
Did this page help you?
