This blog post was originally posted in the ATG Developer Community by Spark::red’s co-founding partner Devon Hillard in July, 2008. Might be slightly different with ATG 10.X, but the fundamentals are still useful.

If you’ve extended an existing PaymentStatus implementation, or if you’ve added a new one as part of adding a new payment type, you may be wondering how you get it persisted.

The docs (at least 2006.3) don’t really help. You can sort of follow the instructions in the Extending the Purchase Process section of the commerce programming docs, but there isn’t much payment status specific info.

I’m assuming you’ve managed to create the new Payment Status, and ensure it’s populated correctly.

So you have a custom Payment Status class, MyPaymentStatus.class, and in your payment processors, you are populating it with the data you need.

Next you need to create an item descriptor for it in the /atg/commerce/order/orderrepository.xml repository definition. If you’ve sub-typed PaymentStatusImpl, or one of it’s children, in your MyPaymentStatus class, then you’ll probably want to sub-type the paymentStatus item descriptor as well. So, in the orderrepository.xml you need to do two things.

First, setup a new option for the type property of the paymentStatus item descriptor:

orderrepository.xml

<item-descriptor name="paymentStatus" xml-combine="append">
    <table shared-table-sequence="1" name="dcspp_pay_status" type="primary" id-column-name="status_id">
        <property name="type" display-name-resource="type" data-type="enumerated" queryable="true" readable="true"
            hidden="false" category-resource="categoryInfo" expert="true" required="false" cache-mode="inherit" writable="true"
            default="paymentStatus">
            <attribute name="useCodeForValue" value="false" />
            <option code="0" value="creditCardStatus" />
            <option code="1" value="giftCertificateStatus" />
            <option code="2" value="paymentStatus" />
            <option code="4000" value="storeCreditStatus" />
            <option code="4" value="myPaymentStatus" />
            <attribute name="propertySortPriority" value="10" />
        </property>
    </table>
</item-descriptor>

The key line is the option code=”4″ line. This sets up a new sub-type for your new item descriptor. Next you have to define your paymentStatus sub-type item:

orderrepository.xml
<item-descriptor sub-type-value="myPaymentStatus" name="myPaymentStatus" display-name-resource="itemDescriptor MyPaymentStatus"
    folder="false" use-id-for-path="false" super-type="paymentStatus" hidden="false" expert="false" content="false"
    writable="true" cache-mode="simple" default="false" item-cache-timeout="180000" id-separator=":">
    <attribute name="categoryBasicsPriority" value="10" />
    <attribute name="categoryStatusPriority" value="20" />
    <attribute name="categoryInfoPriority" value="90" />
    <table shared-table-sequence="1" name="my_payment_status" type="auxiliary" id-column-name="status_id">
        <property name="authCode" display-name-resource="authCode" data-type="string" queryable="true" readable="true"
            column-name="auth_code" hidden="false" category-resource="categoryStatus" expert="false" required="false"
            cache-mode="inherit" writable="true">
            <attribute name="propertySortPriority" value="10" />
        </property>
        <property name="authResponse" display-name-resource="authResponse" data-type="string" queryable="true"
            readable="true" column-name="auth_response" hidden="false" category-resource="categoryStatus" expert="false"
            required="false" cache-mode="inherit" writable="true">
            <attribute name="propertySortPriority" value="20" />
        </property>
        <property name="authSubResponse" display-name-resource="authSubResponse" data-type="string" queryable="true"
            readable="true" column-name="auth_sub_response" hidden="false" category-resource="categoryStatus" expert="false"
            required="false" cache-mode="inherit" writable="true">
            <attribute name="propertySortPriority" value="30" />
        </property>
        <property name="requestId" display-name-resource="requestId" data-type="string" queryable="true" readable="true"
            column-name="request_id" hidden="false" category-resource="categoryStatus" expert="false" required="false"
            cache-mode="inherit" writable="true">
            <attribute name="propertySortPriority" value="40" />
        </property>
        <property name="requestToken" display-name-resource="requestToken" data-type="string" queryable="true"
            readable="true" column-name="request_token" hidden="false" category-resource="categoryStatus" expert="false"
            required="false" cache-mode="inherit" writable="true">
            <attribute name="propertySortPriority" value="50" />
        </property>
    </table>
</item-descriptor>

You’ll need to create the my_payment_status table, using sql like this:

my_payment_status.sql
create table my_payment_status(
    status_id           varchar2(40)    not null,
    auth_code           varchar2(256)   null,
    auth_response       varchar2(256)   null,
    auth_sub_response   varchar2(256)   null,
    request_id          varchar2(256)   null,
    request_token       varchar2(256)   null
    ,constraint mypay_status_p primary key (status_id)
    ,constraint mypaylstats_d_f foreign key (status_id) references dcspp_pay_status (status_id));
commit;

Looks good right? And if you’ve setup a custom PaymentGroup before and gotten it to persist, you’d think be pretty much done. However, it doesn’t actually persist anything.

You need to add all of your new properties to the configurations of two components:

  • /atg/commerce/order/processor/LoadPaymentStatusObjects
  • /atg/commerce/order/processor/SavePaymentStatusObjects

Add this to the appropriate .properties files in your config layer:

*PaymentStatusObjects.properties
savedProperties+=
  requestId,
  requestToken,
  authCode,
  authResponse,
  authSubResponse

Now, it should work.