I have recently download the Java API. Have been making a higher level API for integration into a subscription service. In trying to get the data to make a dropdown list of a customers payment profiles, I am performing a GET_CUSTOMER_PROFILE transaction. From the Result, I am getting the payment profile list. For each payment profile, I was getting the Payment, but find it is not returned by the API as single object, but a list.
My question is, if there is more than one Payment item, which one(s) do I use? I do not actually have a way to test this code, since all I have so far is this forum account. Did not really see anyone else asking this question before. Here is the nearly self-contained method:
public static String[] getPaymentProfileDescs(final String cust_profile_id) throws Exception { final net.authorize.cim.Transaction transaction = instance.merchant.createCIMTransaction(TransactionType.GET_CUSTOMER_PROFILE); transaction.setCustomerProfileId(cust_profile_id); final Result<Transaction> result = (Result<Transaction>) instance.merchant.postTransaction(transaction); if (result.isOk() ){ final ArrayList<PaymentProfile> paymentProfileList = result.getCustomerPaymentProfileList(); final int sz = paymentProfileList.size(); final String[] ret = new String[sz]; CreditCard cc; BankAccount ba; // loop through each of the payment profiles in the list for (int i = 0, c = 0; i < sz; i++){ final PaymentProfile pp = paymentProfileList.get(i); // Should it be assumed that there is only 1 payment per payment profile? // If so, then why is there a list? If not, read first? Last? final Payment payment = pp.getPaymentList().get(0); // description depends on where it is a credit card (last 4), or bank account(Name) if ((cc = payment.getCreditCard()) != null){ final String ccn = cc.getCreditCardNumber(); if (ccn != null && ccn.length() > 4) ret[c++] = pp.getCustomerPaymentProfileId() + "|" + ccn.substring(ccn.length() - 4); }else if ((ba = payment.getBankAccount()) != null){ final String ban = ba.getBankAccountName(); if (ban != null && ban.length() > 0) ret[c++] = pp.getCustomerPaymentProfileId() + "|" + ban; } } return ret; }else throw new Exception(getResultMessages(result) ); }
01-18-2012 09:37 AM
Make it a bit more readable here:
public static String[] getPaymentProfileDescs(final String cust_profile_id) throws Exception { final net.authorize.cim.Transaction transaction = instance.merchant.createCIMTransaction(TransactionType.GET_CUSTOMER_PROFILE); transaction.setCustomerProfileId(cust_profile_id); final Result<Transaction> result = (Result<Transaction>) instance.merchant.postTransaction(transaction); if (result.isOk() ){ final ArrayList<PaymentProfile> paymentProfileList = result.getCustomerPaymentProfileList(); final int sz = paymentProfileList.size(); final String[] ret = new String[sz]; CreditCard cc; BankAccount ba; // loop through each of the payment profiles in the list for (int i = 0, c = 0; i < sz; i++){ final PaymentProfile pp = paymentProfileList.get(i); // Assumed only 1 payment per payment profile? // If so, then why a list? If not, read first? Last? final Payment payment = pp.getPaymentList().get(0); // desc for credit card(last 4), or bank account(Name) if ((cc = payment.getCreditCard()) != null){ final String ccn = cc.getCreditCardNumber(); if (ccn != null && ccn.length() > 4) ret[c++] = pp.getCustomerPaymentProfileId() + "|" + ccn.substring(ccn.length() - 4); }else if ((ba = payment.getBankAccount()) != null){ final String ban = ba.getBankAccountName(); if (ban != null && ban.length() > 0) ret[c++] = pp.getCustomerPaymentProfileId() + "|" + ban; } } return ret; }else throw new Exception(getResultMessages(result) ); }
01-18-2012 10:41 AM
Does seem a bit odd. Do you have a way to var dump the whole structure? How about trace this back to the XML and dump that as well? Might give a better idea as to how things are set up when there's more than one payment profile / payment method.
01-18-2012 04:36 PM
Not sure what var dump is, but I am integrating at source code level. This means I can control-click any of Authorize's method I am calling, and the Netbeans IDE opens up the source class in another tab & jumps to the spot of source of the method. Been doing a lot of that.
Just got a developer account today, but all changes have not been roughed in, so cannot compile at this time. When done though, the Authorize source reads that both input & raw outputs can be echoed to log file with either of their sandbox modes.
One way to look at it is, I never have to worry about it, if I never permit multiple payments in a payment profile. This is enforceable since I am only embedding it in a software license server for products developed in-house.
BTW, how is an expired card remedied? A create of new payment profile & delete of old, or update existing?
01-19-2012 09:12 AM
You can do it either way, but updating is probably more efficient.
01-19-2012 11:17 AM
If I understand correctly, it looks like the "transaction" you are running is actually a request to get a customer profile. In this case, it is quite possible that there will be multiple payment options on file. As far as which of these payment options to select, this is something that depends on the history of how the customer profile was created. A common use case would be to present the customer with a list of the payment options you have on file for them and to let them select which one they want to use for a given transaction.
Also, it's worth noting that an "update" request can be accomplished without knowing the full card number. You can submit the redacted card number and a new expiration date. This generally makes it the preferable option to update an expired card.
01-31-2012 02:40 PM