====== CashNet - Technical Specification ====== ===== Objective ======= Adopting CashNet payment processor to the Learnexa checkout process. Enabling CashNet for credit card payments. ===== Functionality ======= Adding CashNet as an additional payment processor where Clients cannot use WePay or PayPal. Therefore, the Learnexa checkout process needs to be modified to enable CashNet for credit card payments. ===== Workflow ======= ==== Merchant account set up ==== Provide an option in merchant account page to set up cashnet as the payment gateway.\\ Once cashnet is selected, user has to configure Cashnet in learnexa by providing the below required details:\\ - Merchant code - Client code [This will be generated by learnexa and displayed to the user for the user to configure the same as the cashnet store notification url] - Customre ID - PMT CODE === DB Changes === - Merchant code can be saved to the existing "account_id" column - 2 columns have to be added to Merchant account table ^ Column_name ^ type ^ Description ^ | client_code | varchar | Column to hold the client url (store notification url) | | customer_id | varchar | Column to hold custcode to make the purchase | | pmt_code | varchar | Column to hold pmtcode to make the purchase | === Model level Changes === - Create a new model, cashnet_account.rb class CashnetAccount < MerchantAccount end ==== Disable product monthly subscription ==== Since cashnet doesnt provide an option similar to wepay's preapproval, we would not be able to support product monthly subscription using cashnet. If the merchant account of the site is of type cashnet, then product monthly subscription option in pricing options page should be disabled. ==== Product purchase flow==== Once the pay button in the cart is clicked, follow the similar procedure as we do for other payment methods. * Prepare order and payment records with payment_method set to 'Cashnet'. * Purchase status is set to 'processing'. * Generate necessary parameters to payment gateway params = { :merchant => merchant_code, :client => client_code (something like: cashnet_order_checkout_success_url(payer.params_for_url_path(true, true))), :ref1type1 => order_id (We can provide “reftype” and “refval” fields and values in the request if they need to be received in the response), :ref1val1 => order.id, :itemcnt => Total number of items in the cart, :itemcode1 => itemcode 1, :itemcode2 => itemcode 2, .. :itemcoden => itemcode n, :amount => total amount of the items in cart, :qty => 1 (This will always be ‘1’ since there each item in the Learnexa cart is implicitly qty of 1.), :custcode => customer id, :pmtcode => pmtcode } * update the payment transaction table with the parameters. * Change payment status to 'Checkout' * Change cart status to 'Ordered' * Pass the above information to cashnet's server using SSL-encrypted HTTP messages. https://commerce.cashnet.com/{MERCHANT_CODE} * The user is sent to cashnet.com to make the payment. * Once payment is made, cashnet notifies us about the payment status through 'Store notification URL'. * If Payment is success: - Change cart status to 'Complete' - Update payment record with the payment status - Enroll the items in the cart to the user - Clear the cart - Update session[:order_checkout_success] to the order id - Redirect the user to catalog page. * If Payment is failure: - Update payment record with payment status - Redirect the user to catalog page, with the cart open * Ignore any duplicate notification from Cashnet. As specified Cashnet send multiple notifications to ensure the notification is properly received. ===== Security ===== 1. Implement a “shared secret”. This is a secret token/password that is known only to CASHNet and Learnexa server, and never exposed to the user. Learnexa will then only accept Store Notification messages that contain the shared secret. To implement the Store Notification shared secret: * Create a config file "cashnet_config". * Assign a random alphanumeric string as shared-secret E.g. “shared-secret: 1n2bxn5h” * In the CASHNet vendor interface append a slash and your shared secret to the end of both Store Notification URLs (success and failure URLs) E.g. “https://learnexa.com/cashnet/order_checkout_success/1n2bxn5h”. * Store Notification messages should now only be accepted if they contain the configured shared secret. 2. Implement a “shared secret” for every payment request. This is a secret token/password that is specific to the payment object and never exposed to the user. Learnexa will then only accept Store Notification messages specific to the order only if it contain the shared secret specific to the payment object. To implement the Store Notification shared secret: * Pass a shared secret with every payment request E.g. “ref2type1 => 'shared_secret'” * Assign a alphanumeric string as shared-secret (Formula: 'O-' + order.id + '-P-' + order.payment.id + '-TS-' + order.payment.created_at) E.g. “ref2val1: O-order_id-P-payment_id-TS-payment_created_at” * Store Notification messages should now only be accepted if the shared_secret in the response is the same as the shared_secret of the order (as the order id is passed as a ref for the payment) as per the shared secret formula. 3. Restricting the Store Notification URL so that it can only be called by CASHNet’s server IP addresses. Set postback-allowed-ip option in the config file. However, this is only viable if CASHNet can guarantee the ip address does not change. ===== Open questions ===== - I am not able to find a stage/sandbox site for cashnet to test the payment itegration. - If a stage site is available we could try making payments and figure out: - If we can implement lightbox way of handling payments. - If cashnet sends out Store notification messages immediately after making the purchase. - If there will be a chance for cashnet to chargeback the payment. - Cashnet's server IP from which the Store notification URL will be sent is not known. ===== Reference ===== - Requirement document - {{:bostoncollege-learnexa-reqts-0-10a.pdf|}} - CashNet Guide - {{:emarket_checkout_technical_users_guide.rtf|}} - Cashnet store settings - {{:cashnetstoresettings.doc|}}