【问题标题】:Updating and Deleting Payment Methods with Acumatica API使用 Acumatica API 更新和删除付款方式
【发布时间】:2015-07-26 19:05:06
【问题描述】:

感谢Creating customer payment method with api 上的帖子,我能够使用 API 成功创建新的付款方式。但我不知道如何更新或删除现有的付款方式。似乎没有任何类型的关键字段。我已经使用 API 更新和删除了联系人和位置,但联系人有联系人 ID,而位置有 LocationID。似乎没有 PaymentMethodID。我想也许是“卡/帐号”。 field 可能会起到这样的作用,但我无法做到这一点。而且我注意到我可以保存两个具有相同卡号的付款方式,这样如果仍然使用该字段,就会生成相同的密钥。

这是我尝试更新的代码。它主要是我链接到的另一篇文章中 Chris 的代码,但试图为更新添加一个额外的关键字段。

Public Function UpdateCreditCard(ByVal customerID As String, ByVal existingAcctNum As String, ByVal paymentMethodCode As String, ByVal CCNum As String, ByVal expiration As String, ByVal nameOnCard As String, ByVal active As Boolean)
    Dim paymentMethod As AR303010Content = m_context.AR303010GetSchema()
    m_context.AR303010Clear()

    ' main level fields
    Dim customerVal As Value = CreateValue(paymentMethod.PaymentMethodSelection.Customer, customerID)
    Dim paymentMethodCodeVal As Value = CreateValue(paymentMethod.PaymentMethodSelection.PaymentMethod, paymentMethodCode)

    ' inner level fields
    Dim ccNumName As Value = CreateValue(paymentMethod.PaymentMethodDetails.Description, "CCDNUM")
    Dim ccNumValue As Value = CreateValue(paymentMethod.PaymentMethodDetails.Value, CCNum, True)

    Dim ccExpName As Value = CreateValue(paymentMethod.PaymentMethodDetails.Description, "EXPDATE")
    Dim ccExpValue As Value = CreateValue(paymentMethod.PaymentMethodDetails.Value, expiration, True)

    Dim ccNameName As Value = CreateValue(paymentMethod.PaymentMethodDetails.Description, "NAMEONCC")
    Dim ccNameValue As Value = CreateValue(paymentMethod.PaymentMethodDetails.Value, nameOnCard, True)

    Dim saveCommands() As Command
    If existingAcctNum = "" Then
        ' new credit card
        saveCommands = {customerVal, paymentMethod.Actions.Insert, paymentMethodCodeVal, ccNumName, ccNumValue, ccExpName, ccExpValue, ccNameName, ccNameValue, paymentMethod.Actions.Save}
    Else
        ' existing credit card, only allow update of Active or expiration based on "description"
        Dim descriptionVal As Value = CreateValue(paymentMethod.PaymentMethodDetails.Description, existingAcctNum)
        Dim activeVal As Value = CreateValue(paymentMethod.PaymentMethodSelection.Active, active.ToString())
        saveCommands = {customerVal, descriptionVal, ccExpName, ccExpValue, activeVal, paymentMethod.Actions.Save}
    End If
    Dim updateResult As AR303010Content() = m_context.AR303010Submit(saveCommands)

    Return ""
End Function

另一个令人困惑的部分是,我真正想让用户更新的两个字段是到期日期,或者卡是否处于活动状态。但活动标志是可从客户屏幕访问的列表中的字段之一,而到期日期是只能从付款方式屏幕访问的字段。如果这是两个不同的 API 调用,那么我需要在每个调用中使用不同的键字段吗?

【问题讨论】:

    标签: acumatica


    【解决方案1】:

    由于几个不同的原因,此屏幕难以通过 Web 服务使用:

    1. 屏幕上没有可用于定位付款方式的唯一键。内部键是一个名为 PMInstanceID 的字段,虽然技术上您可以通过 Web 服务命令引用它,但使用起来并不明显
    2. 在 Acumatica 中,一旦记录了使用此付款方式的一笔交易,付款方式详细信息就会被锁定。这意味着要对其进行修改,您需要创建一种新的付款方式,并将旧的付款方式设为无效。
    3. 屏幕中有一个错误,该错误仅在通过 Web 服务使用时才会出现,这与上述项目有关。加载支付方式时,如果有任何交易,系统将禁用支付方式详细信息,但如果没有,系统将无法重新启用它。从网络浏览器使用 Acumatica 时,这绝不是问题,因为在每次往返之间会自动重新启用这些字段。但是,当通过 Web 服务自动执行此屏幕时,您实际上是在一次往返中执行所有操作。已报告此问题并将很快修复(内部 JIRA 参考为 AC-54456)

    话虽如此,我们可以使用一些东西来使此屏幕与其他屏幕一样易于通过 Web 服务使用,并解决其局限性。通过创建自定义项目,我们可以在屏幕上添加 PMInstanceID 字段(以下简称 Token ID 字段)。您可以将此令牌存储在您的系统上,并将其用于付款方式的未来操作。在同一个定制项目中,我们还可以始终启用付款方式详细信息,让您可以更新现有卡的到期日期。这样做还解决了上面提到的系统不允许您向系统添加任何新付款方式的错误。自定义分为两部分:

    1. 覆盖 CustomerPaymentMethod DAC 以使 PMInstanceID 字段可从 UI 访问。这是通过将 PXUIField 属性附加到 PMInstanceID 字段来完成的:[PXUIField(DisplayName="Token ID", Visibility=PXUIVisibility.SelectorVisible)]。之后,可以使用布局编辑器将字段添加到屏幕。
    2. 处理CustomerPaymentMethod_RowSelected 事件以强制始终启用付款方式详细信息。在添加新的支付方式时,我们还使用此事件处理程序来隐藏 Token ID 字段,因为在保存支付方式之前,该字段将显示int.MinValue。该事件的完整代码如下所示:

      protected void CustomerPaymentMethod_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
      {
        if(InvokeBaseHandler != null)
          InvokeBaseHandler(cache, e);
      
        // Force the payment method details to always be enabled to facilitate working via web services
        PXUIFieldAttribute.SetEnabled(Base.Details.Cache, null, true);
      
        // When adding a new method, field will have a temporary value corresponding to int.MinValue - don't show it
        PXUIFieldAttribute.SetVisible<CustomerPaymentMethod.pMInstanceID>(cache, e.Row, cache.GetStatus(e.Row) != PXEntryStatus.Inserted);
      }
      

    定制发布后,更新现有支付方式会变得容易得多。下面的代码显示了如何添加付款方式,并检索您稍后将用于更新付款方式的令牌 ID:

        public int AddCreditCard(string customerID, string paymentMethod, string cardNumber, string expirationDate, string cvv, string nameOnCard)
        {
            if(_AR303010 == null) _AR303010 = _context.AR303010GetSchema();
            _context.AR303010Clear();
    
            var commands = new Command[]
            {
                new Value { Value = customerID, LinkedCommand = _AR303010.PaymentMethodSelection.Customer },
                new Value { Commit = true, LinkedCommand = _AR303010.Actions.Insert },
                new Value { Value = paymentMethod, LinkedCommand = _AR303010.PaymentMethodSelection.PaymentMethod },
                new Value { Value = "CCDNUM", LinkedCommand = _AR303010.PaymentMethodDetails.Description },
                new Value { Value = cardNumber, LinkedCommand = _AR303010.PaymentMethodDetails.Value, Commit = true },
                new Value { Value = "EXPDATE", LinkedCommand = _AR303010.PaymentMethodDetails.Description },
                new Value { Value = expirationDate,  LinkedCommand = _AR303010.PaymentMethodDetails.Value, Commit = true},
                new Value { Value = "CVV", LinkedCommand = _AR303010.PaymentMethodDetails.Description },
                new Value { Value = cvv, LinkedCommand = _AR303010.PaymentMethodDetails.Value, Commit = true },
                new Value { Value = "NAMEONCC", LinkedCommand = _AR303010.PaymentMethodDetails.Description },
                new Value { Value = nameOnCard,  LinkedCommand = _AR303010.PaymentMethodDetails.Value, Commit = true },
                _AR303010.Actions.Save,
                _AR303010.PaymentMethodSelection.TokenID
            };
    
            var result = _context.AR303010Submit(commands.ToArray());
            return int.Parse(result[0].PaymentMethodSelection.TokenID.Value);
        }
    
        public void UpdateCreditCardExpirationDate(string customerID, string paymentMethod, int tokenID, string expirationDate)
        {
            if (_AR303010 == null) _AR303010 = _context.AR303010GetSchema();
            _context.AR303010Clear();
    
            var commands = new Command[]
            {
                new Value { Value = customerID, LinkedCommand = _AR303010.PaymentMethodSelection.Customer },
                new Value { Commit = true, LinkedCommand = _AR303010.Actions.Insert },
                new Value { Value = paymentMethod, LinkedCommand = _AR303010.PaymentMethodSelection.PaymentMethod },
                new Value { Value = tokenID.ToString(), LinkedCommand = _AR303010.PaymentMethodSelection.TokenID },
                new Value { Value = "EXPDATE", LinkedCommand = _AR303010.PaymentMethodDetails.Description },
                new Value { Value = expirationDate,  LinkedCommand = _AR303010.PaymentMethodDetails.Value, Commit = true},
                _AR303010.Actions.Save,
            };
    
            var result = _context.AR303010Submit(commands.ToArray());
        }
    
        public void MakeCardInactive(string customerID, string paymentMethod, int tokenID)
        {
            if (_AR303010 == null) _AR303010 = _context.AR303010GetSchema();
            _context.AR303010Clear();
    
            var commands = new Command[]
            {
                new Value { Value = customerID, LinkedCommand = _AR303010.PaymentMethodSelection.Customer },
                new Value { Commit = true, LinkedCommand = _AR303010.Actions.Insert },
                new Value { Value = paymentMethod, LinkedCommand = _AR303010.PaymentMethodSelection.PaymentMethod },
                new Value { Value = tokenID.ToString(), LinkedCommand = _AR303010.PaymentMethodSelection.TokenID },
                new Value { Value = "False", LinkedCommand = _AR303010.PaymentMethodSelection.Active },
                _AR303010.Actions.Save,
            };
    
            var result = _context.AR303010Submit(commands.ToArray());
        }
    

    我把这3个函数封装成一个类,实际使用就变得很简单了:

        var paymentMethodManager = new PaymentMethodManager(context);
        int tokenID = paymentMethodManager.AddCreditCard("ABARTENDE", "MASTERCARD", "5111111111111118", "122016", "123", "John Doe");
        paymentMethodManager.UpdateCreditCardExpirationDate("ABARTENDE", "MASTERCARD", tokenID, "032017");
        paymentMethodManager.MakeCardInactive("ABARTENDE", "MASTERCARD", tokenID);
    

    目前,无法删除现有的付款方式,您必须将其设为非活动状态。我已经提出了这个增强的请求,它可能会在未来出现。

    注意:我已将此答案中使用的所有代码放在 GitHub 上 https://github.com/gmichaud/acumatica-paymentmethod-ws-extensions

    【讨论】:

      猜你喜欢
      • 2014-12-28
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 2011-07-15
      • 2015-03-11
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      相关资源
      最近更新 更多