感谢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调用,那么我是否需要在每个调用中使用不同的键字段?
答案 0 :(得分:1)
由于以下几个原因,此屏幕很难通过网络服务使用:
话虽如此,我们可以使用一些东西来使这个屏幕像其他屏幕一样易于使用Web服务,并解决其局限性。通过创建自定义项目,我们可以将PMInstanceID字段(此处称为令牌ID字段)添加到屏幕。您可以将此令牌存储在系统上,并将其用于将来使用付款方式进行的操作。在同一个自定义项目中,我们还可以使支付方法详细信息始终启用,允许您更新现有卡上的到期日期。这样做也解决了上面提到的错误,系统不允许您向系统添加任何新的付款方式。定制有两个部分:
CustomerPaymentMethod
DAC,以便从UI访问PMInstanceID字段。这是通过将PXUIField属性附加到PMInstanceID字段来完成的:[PXUIField(DisplayName="Token ID", Visibility=PXUIVisibility.SelectorVisible)]
。之后,可以使用布局编辑器将该字段添加到屏幕。 处理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);
}
自定义发布后,更新现有付款方式变得更加容易。以下代码显示了如何添加付款方式,以及检索稍后将用于更新付款方式的令牌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上。