There are 2 parts for explaining this: technical and logical
We see payment as a logical entity that has a life span. For one single payment, you can have multiple authorization transaction retries (Only one success), you can have multiple partial refunds, multiple partial captures, chargebacks, and so forth. See more info here.
The technical reason for doing so is developer-oriented.
To ensure completeness, correctness, and expected behavior, we designed our API to adhere to RESTful standards. This means resource-based development, where each resource supports CRUD operations only and in which the HTTP status code standards are specific to each resource.
With the approach outlined above in the back of our mind, we created a REST resource for Payment, as well as REST resources for Charges, Authorization, Refunds, Chargebacks, and any other financial transaction type. This allows us to correctly enforce idempotency and error handling when handling request retries that would result in the recreation of a resource. For instance, there is a significant difference between retrying (due to a network failure) the creation of a logical Payment resource vs. retrying a financial charge request. The developer might want to handle such cases differently. Likewise, there are major differences in the manner in which timeouts are managed with each of the resources (a Payment is immediate, while Charges run through the entire payment network stack).
In a standard implementation, the introduction of a separate Payment resource does not introduce additional complexity. You can create a Payment and immediately create the Charge like so:
- POST /Payments/
- POST /Payments/<payment_id>/Charges
The effort of building the requests bodies for the requests shown above is similar to building an aggregated body payload for a single request.