この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

非同期ゲートウェイアダプタの作成

非同期支払設定では、支払プラットフォームは最初にトランザクション情報をゲートウェイに送信します。ゲートウェイはトランザクションから受信した肯定応答を使用して応答し、その後、プラットフォームが保留中のトランザクションを作成します。ゲートウェイが通知を送信します。この通知には最終的なトランザクションの状況が含まれます。その後、これに従ってプラットフォームがトランザクションの状況を更新します。

非同期プロセスは、最初のゲートウェイ要求後にプラットフォームが保留中のトランザクションを作成しない同期トランザクションとは異なります。代わりに、ゲートウェイが最終的なトランザクションの状況が含まれる応答を送信した後にのみ、プラットフォームはトランザクションを作成します。同期アダプタの作成については、「同期ゲートウェイアダプタの作成」を参照してください。

非同期設定には、同期ゲートウェイアダプタと非同期アダプタの両方が必要です。このトピックでは、いくつかの重要な領域を見ていくことで、非同期アダプタのサンプルを分析していきます。
  • 非同期支払ゲートウェイアダプタの定義
  • 最初の支払要求の処理
  • 支払ゲートウェイからの通知の処理
  • システムデバッグログを使用したゲートウェイ応答のデバッグ。

支払ゲートウェイアダプタは、future コール、System.Http を使用した外部コールアウト、非同期コール、queueable コールを行ったり、SOQL を使用して DML を実行したりすることはできません。

メモ

非同期支払ゲートウェイアダプタ定義

非同期ゲートウェイアダプタクラスでは、PaymentGatewayAdapter インターフェースPaymentGatewayAsyncAdapter インターフェースの両方を実装する必要があります。アダプタクラスでは、PaymentGatewayAdapter の processRequest メソッドと PaymentGatewayAsyncAdapter の processNotification メソッドも実装する必要があります。

1global with sharing class SampleAdapter implements commercepayments.PaymentGatewayAsyncAdapter, commercepayments.PaymentGatewayAdapter {
2    global SampleAdapter() {}
3    
4    global commercepayments.GatewayResponse processRequest(commercepayments.paymentGatewayContext gatewayContext) {
5    }
6    
7    global commercepayments.GatewayNotificationResponse processNotification(commercepayments.PaymentGatewayNotificationContext gatewayNotificationContext) {
8    }
9}

最初の支払要求の処理

支払プラットフォームは支払 API 要求を受信すると、さらに評価を行うために要求をゲートウェイアダプタに渡します。アダプタは、非同期支払フローの最初のステップを表す processRequest メソッドをコールして要求評価プロセスを開始します。processRequest 実装は 3 つの部分に分けることができます。

最初に、ゲートウェイで理解できる支払要求オブジェクトを作成します。

1commercepayments.RequestType requestType = gatewayContext.getPaymentRequestType();
2if (requestType == commercepayments.RequestType.Capture) {
3   req.setEndpoint('/pal/servlet/Payment/v52/capture');
4    body = buildCaptureRequest((commercepayments.CaptureRequest)gatewayContext.getPaymentRequest());
5} else if (requestType == commercepayments.RequestType.ReferencedRefund) {
6    req.setEndpoint('/pal/servlet/Payment/v52/refund');
7    body = buildRefundRequest((commercepayments.ReferencedRefundRequest)gatewayContext.getPaymentRequest());
8}

次に、アダプタが要求を支払ゲートウェイに送信します。

1req.setBody(body);
2req.setMethod('POST');
3commercepayments.PaymentsHttp http = new commercepayments.PaymentsHttp();
4HttpResponse res = null;
5try {
6    res = http.send(req);
7} catch(CalloutException ce) {
8    commercepayments.GatewayErrorResponse error = new commercepayments.GatewayErrorResponse('500', ce.getMessage());
9    return error;
10}
最後に、アダプタが応答オブジェクトを作成し、ゲートウェイの応答からのデータを保存します。応答オブジェクトの種別は、元々行ったのが支払収集要求であったのか返金要求であったのかに応じて異なります。
1if ( requestType == commercepayments.RequestType.Capture) {
2   // Refer to the end of this doc for sample createCaptureResponse implementation
3    response =  createCaptureResponse(res);
4} else if ( requestType == commercepayments.RequestType.ReferencedRefund) {
5    response =  createRefundResponse(res);
6}
7return response;

支払ゲートウェイからの通知の処理

顧客の銀行がトランザクションを処理して結果をゲートウェイに送信したら、ゲートウェイは最終的なトランザクションの状況を提供する準備ができたことを示す通知をアダプタに送信します。非同期トランザクションフローのこの部分のために、アダプタは processNotification クラスをコールする必要があります。processNotification 実装は 4 つの部分に分けることができます。

最初に、アダプタが通知要求の署名を確認します。署名の確認についての詳細は、[TOPIC] を参照してください。

1private Boolean verifySignature(NotificationRequest requestItem) {
2    String payload = requestItem.pspReference + ':'
3        + (requestItem.originalReference == null ? '' : requestItem.originalReference) + ':'
4        + requestItem.merchantAccountCode + ':'
5        + requestItem.merchantReference + ':'
6        + requestItem.amount.value.intValue() + ':'
7        + requestItem.amount.currencyCode + ':'
8        + requestItem.eventCode + ':'
9        + requestItem.success;
10    String myHMacKey = getHMacKey();
11    String generatedSign = EncodingUtil.base64Encode(Crypto.generateMac('hmacSHA256', Blob.valueOf(payload), 
12                                EncodingUtil.convertFromHex(myHMacKey)));
13    return generatedSign.equals(requestItem.additionalData.hmacSignature);
14}
次に、アダプタがゲートウェイの通知要求を解析し、通知オブジェクトを作成します。getPaymentGatewayNotificationRequest メソッドによってゲートウェイの通知要求項目からのデータが評価されます。これには、状況、referenceNumber、イベント、金額が含まれます。プラットフォームが正常に通知を受信したかどうかに基づいて、notificationStatus オブジェクトが [成功] または [失敗] に設定されます。通知のイベントコードでゲートウェイが支払収集トランザクションを処理したことが示されている場合、アダプタは CaptureNotification クラスを使用して通知オブジェクトを作成します。イベントコードでゲートウェイが返金トランザクションを処理したことが示されている場合、アダプタは ReferencedRefundNotification クラスを使用して通知オブジェクトを作成します。
1commercepayments.PaymentGatewayNotificationRequest gatewayNotificationRequest = gatewayNotificationContext.getPaymentGatewayNotificationRequest();
2Blob request = gatewayNotificationRequest.getRequestBody();
3SampleNotificationRequest notificationRequest = SampleNotificationRequest.parse(request.toString().replace('currency', 'currencyCode'));                
4List<SampleNotificationRequest.NotificationItems> notificationItems = notificationRequest.notificationItems;
5SampleNotificationRequest.NotificationRequestItem notificationRequestItem = notificationItems[0].NotificationRequestItem;
6
7Boolean success = Boolean.valueOf(notificationRequestItem.success);
8String pspReference = notificationRequestItem.pspReference;
9String eventCode = notificationRequestItem.eventCode;
10Double amount = notificationRequestItem.amount.value;
11
12commercepayments.NotificationStatus notificationStatus = null;
13if (success) {
14    notificationStatus = commercepayments.NotificationStatus.Success;
15} else {
16    notificationStatus = commercepayments.NotificationStatus.Failed;
17}
18commercepayments.BaseNotification notification = null;
19if ('CAPTURE'.equals(eventCode)) {
20    notification = new commercepayments.CaptureNotification();
21} else if ('REFUND'.equals(eventCode)) {
22    notification = new commercepayments.ReferencedRefundNotification();
23}
24notification.setStatus(notificationStatus);
25notification.setGatewayReferenceNumber(pspReference);
26notification.setAmount(amount);
次に、アダプタは支払プラットフォームが通知の結果を記録することを要求します。
1commercepayments.NotificationSaveResult saveResult = commercepayments.NotificationClient.record(notification);
プラットフォームが正常に通知のデータを保存したかどうかに関係なく、すべての非同期ゲートウェイでは、プラットフォームが通知を受信したことを肯定応答する必要があります。プラットフォームは GatewayNotificationResponse クラスをコールして肯定応答を送信します。
1commercepayments.GatewayNotificationResponse gnr = new commercepayments.GatewayNotificationResponse();
2if (saveResult.isSuccess()) {
3    system.debug('Notification accepted by platform');
4} else {
5    system.debug('Errors in the result '+ Blob.valueOf(saveResult.getErrorMessage()));
6}
7gnr.setStatusCode(200);
8gnr.setResponseBody(Blob.valueOf('[accepted]'));
9return gnr;

デバッグ

通常、Apex デバッグログは開発者��ンソールで使用できます。ただし、Salesforce では開発者コンソールの processNotification メソッドからのデバッグログが保存されません。system.debug を使用したメソッドフローのこの部分を確認するには、「デバッグログの設定」の「ゲストユーザのデバッグログの収集」セクションを参照してください。