Install and configure Affirm

This guide walks you through configuring Affirm at checkout in Oracle Commerce (ATG).

Install Affirm on Oracle Commerce (ATG)

Download the Affirm module.

The Affirm module is a packaged ATG module whose structure will be familiar to Oracle Commerce users.

ATG module structure

File/DirectoryDescription
build.properties Module description
build.xml Build file (based on Oracle Commerce Reference Store)
/data Sample data (reference)
/etc JSP files used to integrate the module with Oracle Reference Store (reference)
/lib Libraries required for JSON parsing
/META-INF/MANIEST.MF Module definition
/sql Required SQL for the switching and core schemas
/src Source code for Java and configuration files
/Versioned Base module for Business Control Center (admin)

Since the reference implementation of the Affirm module is based on the Oracle Commerce Reference Store, the build scripts rely on the Oracle Commerce Reference Store build files. You can choose to either keep the module separate from your existing store or integrate the module files into the source code of your existing store.

Maintain a separate module

If you choose to maintain Affirm as a separate module, you'll still need to integrate it into your existing build system so that the Affirm module deploys with your store's main commerce module. Mimic your existing store module's build.xml file structure and include it in the Affirm module. Update ATG-Required in MANIFEST.MF to point to your store's existing module. You'll likely need to update individual files in the Affirm module, so you're required to build and deploy it with the rest of the store. Finally, include the Affirm module in the module list when assembling your EAR file for deployment. If you're specifying a command-line module list when starting your Oracle Commerce instances, then add this module there as well.

Integrate the module

If you choose to integrate the Affirm module files into your existing store commerce module, then copy the files in the /src, /config, and /lib directories into your existing commerce module. Update the MANIFEST.MF to include the JSON libraries in the Affirm module's /lib folder.

Configure Affirm

The following table includes the parameters found in affirm/commerce/payment/AffirmPaymentConfiguration.properties. Edit each parameter to configure Affirm as a payment method.

Property nameTypeDescription
apiVersionstringThis is the Affirm API version (currently 2).
apiUrlstringSet the API URL to https://sandbox.affirm.com/api/v2 (sandbox).
jsUrlstringSet the JavaScript URL to https://cdn1-sandbox.affirm.com/js/v2/affirm.js (sandbox).
enabledbooleanSet to true to enable Affirm checkout option.
capturePaymentOnOrderSubmitbooleanIf your checkout process automatically captures the charge, set to true.
publicAPIKey stringEnter your sandbox public API key.
privateAPIKey stringEnter your sandbox private API key.
defaultRuleId stringSet to the default MFP Program ID.
minimumAmount doubleEnter the minimum dollar amount value that displays Affirm as a payment option.
affirmCancelUrl stringEnter the URL where the customer goes after canceling an order.
affirmConfirmationUrl stringEnter the URL where the customer goes after completing a loan.
moduleVersion stringSet to either version 11.x or 10.x.

Develop your front-end integration for when a customer completes a loan. Be sure to handle the use cases for sending a customer back to the billing page or to a page that submits the order and runs it through an order processing pipeline in your existing store's codebase. These will be custom integrations for each merchant. You can review examples from the Reference Store.

Configure the purchase process

Create standard ATG payment objects and processors to configure the Affirm payment method.

/atg/commerce/order/OrderTools.properties

beanNameToItemDescriptorMap+=\
com.affirm.commerce.payment.AffirmPayment=affirmPaymentGroup
paymentTypeClassMap+=\
affirmPayment=com.affirm.commerce.payment.AffirmPayment

/atg/commerce/payment/PaymentManager.properties

paymentGroupToChainNameMap+=\
com.affirm.commerce.payment.AffirmPayment=affirmPaymentProcessorChain

/atg/commerce/payment/paymentpipeline.xml

<pipelinemanager>
<!-- This chain is used to process a Affirm payment group -->
<pipelinechain name="affirmPaymentProcessorChain" transaction="TX_REQUIRED" headlink="createAffirmPaymentInfo">
    <pipelinelink name="createAffirmPaymentInfo" transaction="TX_MANDATORY">
        <processor jndi="/affirm/commerce/payment/processor/CreateAffirmPaymentInfo" />
        <transition returnvalue="1" link="processAffirmPayment" />
    </pipelinelink>
    <pipelinelink name="processAffirmPayment" transaction="TX_MANDATORY">
        <processor jndi="/affirm/commerce/payment/processor/ProcessAffirmPayment" />
    </pipelinelink>
</pipelinechain>
</pipelinemanager>

/affirm/commerce/payment/processor/CreateAffirmPaymentInfo.properties

$class=com.affirm.commerce.payment.ProcCreateAffirmPaymentInfo
$scope=global
affirmPaymentInfoClass=com.affirm.commerce.payment.AffirmPaymentInfo

/affirm/commerce/payment/processor/ProcessAffirmPayment.properties

$class=com.affirm.commerce.payment.ProcProcessAffirmPaymentImpl
$scope=global
affirmManager=/affirm/commerce/payment/AffirmPaymentUtil
orderTools=/atg/commerce/order/OrderTools

Review Affirm module libraries and processes

The following describes how different libraries and processes work in the Oracle ATG Affirm module. While it is mostly descriptive, there are some references to configurations you can make.

AffirmUtil
com.affirm.commerce.payment.AffirmUtil

This class handles the following API calls to Affirm:

  • Direct Checkout API
  • Authorization
  • Void Authorization
  • Capture
  • Refund (and partial refund)
  • Update Shipping (tracking code, carrier, address)

All code uses a shared method for making the call to Affirm. Enable loggingDebug in this class to view all messages going to and from the API.

AffirmPaymentProcessorImpl

com.affirm.commerce.payment.AffirmPaymentProcessorImpl

This class implements the AffirmPaymentProcessor interface and implements the authorize, debit, decreaseAuthorizationForPaymentGroup, and credit methods. It delegates to AffirmUtil to build the JSON data and invoke the API calls.

AffirmProcessingManager
com.affirm.commerce.payment.AffirmProcessingManager

This class updates the shipping details. This is the only operation that happens outside of the Oracle Commerce payment processing pipeline.

AffirmCheckoutFormHandler
com.affirm.commerce.payment.AffirmCheckoutFormHandler
This class makes the direct checkout API call to Affirm, receives the checkout token and redirect URL, and then sends a local redirect with that URL to the Affirm site.

AffirmPaymentFormHandler
com.affirm.commerce.payment.AffirmPaymentFormHandler
The page the user lands on after returning from the Affirm site invokes this form handler. With the Oracle Commerce Reference Store, this calls the exact same "processOrderBilling" method that credit card orders use. The difference is that Affirm orders use the Affirm payment method instead of credit cards. Your Oracle site should implement this in the same way.

ProcDebitPayment
This processor is included in the processOrder order processing pipeline chain. It captures payment immediately after authorization if AffirmPaymentConfiguration.capturePaymentOnOrderSubmit is set to true. This processor delegates to the out-of-the-box PaymentManager, which calls debit on each payment group in the order. The PaymentManager then finds and invokes the appropriate pipeline chain to run. Orders with the AffirmPayment payment group type invoke the affirmPaymentProcessorChain payment pipeline. This is an example of an order processing pipeline calling the payment processing pipeline.

JSON Objects for Affirm API calls
The POJO objects, which are transformed to JSON, are located in the com.affirm.commerce.payment.json package. The objects included are:

  • AffirmOrder
  • AffirmItem
  • AffirmMetaData
  • AffirmAddress
  • Billing
  • Config
  • Discount
  • Merchant
  • Name
  • Shipping
  • UpdateShipment

AffirmProcessingFormHandler

This is sample code for invoking the void, capture, refund and shipment update API calls. Each Oracle Commerce implementation will have a different entry point for these operations.

Placing the order

The redirect URL sent to Affirm (AffirmPaymentConfiguration.affirmConfirmationUrl) is currently set to the checkout/affirm_post.jsp. That page immediately invokes the AffirmPaymentFormHandler to process the order.

Order Management After Purchase

The file /etc/crs-jsps/checkout/affirm_orders.jsp includes sample code for the refund, void and capture methods.

Affirm Rules

A droplet (com.affirm.rules.AffirmRuleDroplet) will receive order and product parameters and then return a data-promo-id and a data-amount value for the promotional messaging JavaScript. The business logic in the AffirmRuleManager will determine the highest priority rule that the user qualifies for, and return the corresponding data-promo-id for that rule.

com.affirm.rules.AffirmRuleDroplet

Place this droplet on any page that will show the Affirm offer. Here is a sample JSP fragment to invoke the droplet and display the Affirm messaging:

<%-- Import Required Beans --%>
<dsp:importbean bean="/atg/commerce/ShoppingCart"/>
<dsp:importbean bean="/affirm/rules/AffirmRuleDroplet"/>
 
<dsp:droplet name="AffirmRuleDroplet">
    <dsp:param name="order" bean="ShoppingCart.current"/>
    <dsp:param name="product" param="product"/>
    <dsp:param name="sku" param="sku"/>
    <dsp:param name="pageType" param="pageType"/>
    <dsp:oparam name="output">
        <dsp:getvalueof var="dataPromoId" param="dataPromoId"/>
        <dsp:getvalueof var="ruleName" param="ruleName"/>
        <dsp:getvalueof var="dataAmount" param="dataAmount"/>
        <c:choose>
            <c:when test="${not empty dataAmount}">
            <p class="affirm-as-low-as" data-promo-id="${dataPromoId}" data-amount="${dataAmount}" data-affirm-color="blue"></p>
        </c:when>
        <c:otherwise>
            <p class="affirm-as-low-as" data-promo-id="${dataPromoId}" data-affirm-color="blue"></p>
        </c:otherwise>
        </c:choose>
        <!-- Affirm data promo id: ${dataPromoId} -->
        <!-- Affirm rule display name: ${ruleName} -->
    </dsp:oparam>
    <dsp:oparam name="empty">
    <!-- No affirm rule match -->
    </dsp:oparam>
</dsp:droplet>

AffirmRuleManager

com.affirm.rules.AffirmRuleManager

This is class includes all the logic for evaluating the rules.