如何通过 Stripe webhook 响应访问费用

问题描述 投票:0回答:1

在访问 Stripe webhook 上的收费事件时,我总是遇到错误。这是我的 webhook 端点:

    @PostMapping("/webhook")
    public ResponseEntity<String> handlePostPaymentEvent(@RequestHeader("Stripe-Signature") String sigHeader,
                                                     @RequestBody String payload) throws EtBadRequest {
    Event event = null;
    try {
        event = ApiResource.GSON.fromJson(payload, Event.class);
    } catch (JsonSyntaxException e) {
        log.info("⚠️ Webhook error while parsing basic request.");
    }

    if (endpointSecret != null && sigHeader != null) {
        try {
            event = Webhook.constructEvent(payload, sigHeader, endpointSecret);
        } catch (SignatureVerificationException e) {
            log.info("⚠️ Webhook error while validating signature.");
            return ResponseEntity.badRequest().build();
        }
    }

    if (event != null) {
        StripeObject stripeObject = event.getData().getObject();
        PaymentIntent paymentIntent;
        switch (event.getType()) {
            case "payment_intent.succeeded":
                paymentIntent = (PaymentIntent) stripeObject;
                ...
                break;
            case "payment_intent.payment_failed":
                paymentIntent = (PaymentIntent) stripeObject;
                ....
                break;
            case "payment_intent.canceled":
                paymentIntent = (PaymentIntent) stripeObject;
                ...
                break;
            case "charge.succeeded":
                try {
                    Charge charge = (Charge) stripeObject;
                    log.info("Charge Succeeded: " + charge.getId() + " amount: " + charge.getAmount());
                ...
                } catch (Exception e) {
                    throw new EtBadRequest("handlePaymentSucceeded error: " + e);
                }
                break;
            default:
                log.info("Unhandled event type: " + event.getType());
                break;
        }
    }
    return ResponseEntity.ok("");
}

我可以访问 PaymentIntent,但不能在不抛出错误的情况下成功收费。这是错误:

2024-02-29T01:03:31.142+03:00 ERROR 1708 --- [nio-8088-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalStateException: Invocation failure
Controller [com.work.paymentservice.controllers.HomeController]
Method [public org.springframework.http.ResponseEntity<java.lang.String> com.work.paymentservice.controllers.HomeController.handlePostPaymentEvent(java.lang.String,java.lang.String) throws com.work.paymentservice.exceptions.EtBadRequest] with argument values:
 [0] [type=java.lang.String] [value=t=1709157811,v1=7444530d7ce48c206ae3607ddf5661398fc2a653d519ae1940dab581b83b776d,v0=fa1e8ee5e874158194e03144c7dc54b7377771738ee7639c2df7c68fae94427e],
[1] [type=java.lang.String] [value={
  "id": "evt_3OovDZEPlIiUHjr41QRsKsqy",
  "object": "event",
  "api_version": "2017-06-05",
  "created": 1709157811,
  "data": {
    "object": {
      "id": "pi_3OovDZEPlIiUHjr41gnIAEWG",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 162500,
      "amount_capturable": 0,
      "amount_details": {
        "tip": {
        }
      },
      "amount_received": 162500,
      "application": null,
      "application_fee_amount": null,
      "automatic_payment_methods": {
        "allow_redirects": "always",
        "enabled": true
      },
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [
          {
            "id": "ch_3OovDZEPlIiUHjr41KVK4M7P",
            "object": "charge",
            "amount": 162500,
            "amount_captured": 162500,
            "amount_refunded": 0,
            "application": null,
            "application_fee": null,
            "application_fee_amount": null,
            "balance_transaction": "txn_3OovDZEPlIiUHjr41BiKnsDP",
            "billing_details": {
              "address": {
                "city": null,
                "country": null,
                "line1": null,
                "line2": null,
                "postal_code": null,
                "state": null
              },
              "email": null,
              "name": null,
              "phone": null
            },
            "calculated_statement_descriptor": "xxxxxxxxxxPHUB",
            "captured": true,
            "created": 1709157810,
            "currency": "usd",
            "customer": null,
            "description": null,
            "destination": null,
            "dispute": null,
            "disputed": false,
            "failure_balance_transaction": null,
            "failure_code": null,
            "failure_message": null,
            "fraud_details": {
            },
            "invoice": null,
            "livemode": false,
            "metadata": {
            },
            "on_behalf_of": null,
            "order": null,
            "outcome": {
              "network_status": "approved_by_network",
              "reason": null,
              "risk_level": "normal",
              "risk_score": 44,
              "seller_message": "Payment complete.",
              "type": "authorized"
            },
            "paid": true,
            "payment_intent": "pi_3OovDZEPlIiUHjr41gnIAEWG",
            "payment_method": "pm_1OovDqEPlIiUHjr4G2DKp29i",
            "payment_method_details": {
              "card": {
                "amount_authorized": 162500,
                "brand": "visa",
                "checks": {
                  "address_line1_check": null,
                  "address_postal_code_check": null,
                  "cvc_check": "pass"
                },
                "country": "US",
                "exp_month": 4,
                "exp_year": 2024,
                "extended_authorization": {
                  "status": "disabled"
                },
                "fingerprint": "gCaDYUbs2ZkFuyTl",
                "funding": "credit",
                "incremental_authorization": {
                  "status": "unavailable"
                },
                "installments": null,
                "last4": "4242",
                "mandate": null,
                "multicapture": {
                  "status": "unavailable"
                },
                "network": "visa",
                "network_token": {
                  "used": false
                },
                "overcapture": {
                  "maximum_amount_capturable": 162500,
                  "status": "unavailable"
                },
                "three_d_secure": null,
                "wallet": null
              },
              "type": "card"
            },
            "radar_options": {
            },
            "receipt_email": null,
            "receipt_number": null,
            "receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xQVI5YmRFUGxJaVVIanI0KLPb_q4GMgZHSgc81S86LBb9oYrKsttuWf6CTKD02N3wtYnGXB9xcRoeNy8vt0yzbIxSUo0eZxS6NojW",
            "refunded": false,
            "refunds": {
              "object": "list",
              "data": [

              ],
              "has_more": false,
              "total_count": 0,
              "url": "/v1/charges/ch_3OovDZEPlIiUHjr41KVK4M7P/refunds"
            },
            "review": null,
            "shipping": null,
            "source": null,
            "source_transfer": null,
            "statement_descriptor": null,
            "statement_descriptor_suffix": null,
            "status": "succeeded",
            "transfer_data": null,
            "transfer_group": null
          }
        ],
        "has_more": false,
        "total_count": 1,
        "url": "/v1/charges?payment_intent=pi_3OovDZEPlIiUHjr41gnIAEWG"
      },
      "client_secret": "pi_3OovDZEPlIiUHjr41gnIAEWG_secret_jwFMpo4u2gb3oY9Cq3ztxhHeb",
      "confirmation_method": "automatic",
      "created": 1709157793,
      "currency": "usd",
      "customer": null,
      "description": null,
      "invoice": null,
      "last_payment_error": null,
      "latest_charge": "ch_3OovDZEPlIiUHjr41KVK4M7P",
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": "pm_1OovDqEPlIiUHjr4G2DKp29i",
      "payment_method_configuration_details": {
        "id": "pmc_1O3lV6EPlIiUHjr41UDy6M3U",
        "parent": null
      },
      "payment_method_options": {
        "card": {
          "installments": null,
          "mandate_options": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "processing": null,
      "receipt_email": null,
      "review": null,
      "setup_future_usage": null,
      "shipping": null,
      "source": null,
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "succeeded",
      "transfer_data": null,
      "transfer_group": null
    }
  },
  "livemode": false,
  "pending_webhooks": 3,
  "request": {
    "id": "req_YnQLvAzaQz9Ut3",
    "idempotency_key": "81093d3f-ae03-4aeb-8aea-9f76a5c2a799"
  },
  "type": "payment_intent.succeeded"
}] ] with root cause

只要我尝试访问任何充电事件,似乎整个方法都会出现错误。我该如何解决这个问题?

java spring-boot stripe-payments
1个回答
0
投票

示例事件 evt_3OovDZEPlIiUHjr41QRsKsqy 是来自

payment_intent.succeeded
的支付意图对象。应从支付意图对象中检索费用 ID,如下所示:

case "payment_intent.succeeded":
    PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
    String chargeId = paymentIntent.getLatestCharge();
    break;

您可以使用Charge Retrieval API获取费用信息。

© www.soinside.com 2019 - 2024. All rights reserved.