public static Map<String, Object> assembleCrmsfaOrderFormMergeContext( Delegator delegator, String orderId) { Map<String, Object> templateContext = new HashMap<String, Object>(); if (UtilValidate.isNotEmpty(orderId)) { try { OrderReadHelper orh = new OrderReadHelper(delegator, orderId); templateContext.put("orderId", orderId); templateContext.put("externalOrderId", orh.getOrderHeader().get("externalId")); templateContext.put("orderDate", orh.getOrderHeader().getTimestamp("orderDate")); GenericValue billingParty = orh.getBillToParty(); if (UtilValidate.isNotEmpty(billingParty)) { if ("Person".equalsIgnoreCase(billingParty.getEntityName())) { templateContext.put("orderBillingFirstName", billingParty.get("firstName")); templateContext.put("orderBillingLastName", billingParty.get("lastName")); } templateContext.put("orderPartyId", billingParty.get("partyId")); templateContext.put( "orderBillingFullName", org.ofbiz.party.party.PartyHelper.getPartyName(billingParty, false)); } templateContext.put("orderSubtotal", orh.getOrderItemsSubTotal()); templateContext.put("orderTaxTotal", orh.getTaxTotal()); templateContext.put("orderShippingTotal", orh.getShippingTotal()); templateContext.put("orderGrandTotal", orh.getOrderGrandTotal()); templateContext.put( "orderPaymentTotal", orh.getOrderGrandTotal().subtract(UtilOrder.getOrderOpenAmount(orh))); GenericValue shippingParty = orh.getShipToParty(); if (UtilValidate.isNotEmpty(shippingParty)) { if ("Person".equalsIgnoreCase(shippingParty.getEntityName())) { templateContext.put("orderShippingFirstName", shippingParty.get("firstName")); templateContext.put("orderShippingLastName", shippingParty.get("lastName")); } else { templateContext.put("orderShippingCompanyName", shippingParty.get("groupName")); } templateContext.put( "orderShippingFullName", org.ofbiz.party.party.PartyHelper.getPartyName(shippingParty, false)); } List<GenericValue> orderItemVals = orh.getOrderItems(); List<Map<String, Object>> orderItems = new ArrayList<Map<String, Object>>(); for (GenericValue orderItemVal : orderItemVals) { Map<String, Object> orderItem = orderItemVal.getAllFields(); GenericValue product = orderItemVal.getRelatedOne("Product"); if (UtilValidate.isEmpty(product)) { continue; } for (String fieldName : (Set<String>) product.keySet()) { orderItem.put(fieldName, product.get(fieldName)); } orderItems.add(orderItem); } templateContext.put("orderItems", orderItems); } catch (GenericEntityException e) { Debug.logError(e, MODULE); } } return templateContext; }
// Note we're not doing a lot of error checking here as this method is really only used // to confirm the order with PayPal, the subsequent authorizations will handle any errors // that may occur. public static Map<String, Object> doExpressCheckout( DispatchContext dctx, Map<String, Object> context) { LocalDispatcher dispatcher = dctx.getDispatcher(); Delegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference"); OrderReadHelper orh = new OrderReadHelper(delegator, paymentPref.getString("orderId")); Locale locale = (Locale) context.get("locale"); GenericValue payPalPaymentSetting = getPaymentMethodGatewayPayPal(dctx, context, null); GenericValue payPalPaymentMethod = null; try { payPalPaymentMethod = paymentPref.getRelatedOne("PaymentMethod", false); payPalPaymentMethod = payPalPaymentMethod.getRelatedOne("PayPalPaymentMethod", false); } catch (GenericEntityException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } BigDecimal processAmount = paymentPref.getBigDecimal("maxAmount"); NVPEncoder encoder = new NVPEncoder(); encoder.add("METHOD", "DoExpressCheckoutPayment"); encoder.add("TOKEN", payPalPaymentMethod.getString("expressCheckoutToken")); encoder.add("PAYMENTACTION", "Order"); encoder.add("PAYERID", payPalPaymentMethod.getString("payerId")); // set the amount encoder.add("AMT", processAmount.setScale(2).toPlainString()); encoder.add("CURRENCYCODE", orh.getCurrency()); BigDecimal grandTotal = orh.getOrderGrandTotal(); BigDecimal shippingTotal = orh.getShippingTotal().setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal taxTotal = orh.getTaxTotal().setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal subTotal = grandTotal.subtract(shippingTotal).subtract(taxTotal).setScale(2, BigDecimal.ROUND_HALF_UP); encoder.add("ITEMAMT", subTotal.toPlainString()); encoder.add("SHIPPINGAMT", shippingTotal.toPlainString()); encoder.add("TAXAMT", taxTotal.toPlainString()); NVPDecoder decoder = null; try { decoder = sendNVPRequest(payPalPaymentSetting, encoder); } catch (PayPalException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (decoder == null) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingPayPalUnknownError", locale)); } Map<String, String> errorMessages = getErrorMessageMap(decoder); if (UtilValidate.isNotEmpty(errorMessages)) { if (errorMessages.containsKey("10417")) { // "The transaction cannot complete successfully, Instruct the customer to use an // alternative payment method" // I've only encountered this once and there's no indication of the cause so the temporary // solution is to try again boolean retry = context.get("_RETRY_") == null || (Boolean) context.get("_RETRY_"); if (retry) { context.put("_RETRY_", false); return PayPalServices.doExpressCheckout(dctx, context); } } return ServiceUtil.returnError(UtilMisc.toList(errorMessages.values())); } Map<String, Object> inMap = FastMap.newInstance(); inMap.put("userLogin", userLogin); inMap.put("paymentMethodId", payPalPaymentMethod.get("paymentMethodId")); inMap.put("transactionId", decoder.get("TRANSACTIONID")); Map<String, Object> outMap = null; try { outMap = dispatcher.runSync("updatePayPalPaymentMethod", inMap); } catch (GenericServiceException e) { Debug.logError(e, module); return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(outMap)) { Debug.logError(ServiceUtil.getErrorMessage(outMap), module); return outMap; } return ServiceUtil.returnSuccess(); }