使用Acumatica API更新和删除付款方式

时间:2015-05-15 00:27:55

标签: acumatica

感谢Creating customer payment method with api上的帖子,我可以使用API​​成功创建新的付款方式。但我无法弄清楚如何更新或删除现有的付款方式。似乎没有任何类型的关键字段。我已使用API​​更新和删除了“联系人和位置”,但“联系人”具有联系人ID,而“位置”具有“位置ID”。它似乎不是一个PaymentMethodID。我想也许是"卡/账户号码"字段可能会起作用,但我无法完成这项工作。而且我注意到我可以保存两个具有相同卡号的付款方式,因此无论如何都会使用相同的密钥。

这是我尝试更新的代码。它主要是来自我链接的其他帖子的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

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

1 个答案:

答案 0 :(得分:1)

由于以下几个原因,此屏幕很难通过网络服务使用:

  1. 您无法通过屏幕显示唯一键来查找付款方式。内部键是一个名为PMInstanceID的字段,虽然您可以通过Web服务命令从技术上引用它,但使用
  2. 并不明显。
  3. 在Acumatica中,一旦使用此付款方式进行了一次交易,就会锁定付款方式详细信息。这意味着要对其进行修改,您需要创建一种新的付款方式,并将旧的付款方式设置为无效。
  4. 屏幕上有一个错误,只有在通过网络服务使用时才会显示,这与上面的项目有关。加载付款方式时,如果有任何交易,系统将禁用付款方式详细信息,但如果没有,则无法重新启用。从Web浏览器使用Acumatica时,这绝不是问题,因为在每次往返之间会自动重新启用字段。但是,当通过Web服务自动化此屏幕时,您实际上是在一次往返中执行所有操作。此问题已报告并将很快修复(内部JIRA参考号为AC-54456)
  5. 话虽如此,我们可以使用一些东西来使这个屏幕像其他屏幕一样易于使用Web服务,并解决其局限性。通过创建自定义项目,我们可以将PMInstanceID字段(此处称为令牌ID字段)添加到屏幕。您可以将此令牌存储在系统上,并将其用于将来使用付款方式进行的操作。在同一个自定义项目中,我们还可以使支付方法详细信息始终启用,允许您更新现有卡上的到期日期。这样做也解决了上面提到的错误,系统不允许您向系统添加任何新的付款方式。定制有两个部分:

    1. 覆盖CustomerPaymentMethod DAC,以便从UI访问PMInstanceID字段。这是通过将PXUIField属性附加到PMInstanceID字段来完成的:[PXUIField(DisplayName="Token ID", Visibility=PXUIVisibility.SelectorVisible)]。之后,可以使用布局编辑器将该字段添加到屏幕。
    2. 处理CustomerPaymentMethod_RowSelected事件以强制始终启用付款方式详细信息。我们还使用此事件处理程序在添加新的付款方式时隐藏令牌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);
      }
      
    3. 自定义发布后,更新现有付款方式变得更加容易。以下代码显示了如何添加付款方式,以及检索稍后将用于更新付款方式的令牌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);
      

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

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