"Payment" as a single endpoint? As a state? Other?

52 views
Skip to first unread message

Felix S.

unread,
Feb 3, 2015, 7:43:11 AM2/3/15
to api-...@googlegroups.com
Hi,

I'm trying to get a feeling for when things should be endpoints, states in an endpoint or other things.

My current problem is modelling a "Kiosk" (by which I mean rather the german than the english/american concept, but that shouldn't do much to the question :-) ). Currently present:

* /users for the customers,
* /products for the products,
* /carts to save on the server what a customer has already "reserved".

Now I'd like to record an (offline) payment, which will decrease the number of available products, the user's balance, and so on. My understanding would be that this is an operation that would be put in it's own endpoint, so one of:

* POST cart_id=<id> /transactions
* POST /cart/<id>/payment

I have seen other ways to do this by adding a "state" attribute to the cart though, and to transition that from "open" to "paid" for example, and have all the side effects (reduce the number of available products, reduce the balance of the user, maybe other stuff) happen when that transaction happens. I must say I'm not sure I like that approach because it feels like hiding a lot of side effects behind a relatively small change.

Now back to the question. What would you consider the best or most idiomatic way to do this? Is there another way I haven't considered? What are the advantages and disadvantages of one solution vs another, if any?

Thank you for your time,

Felix

Andrew Braae

unread,
Feb 3, 2015, 2:46:54 PM2/3/15
to api-...@googlegroups.com
Do you care about the history of "checkouts" for a cart?

e.g.:
- how many fail due to credit card failures?
- how long after first loading up the cart does the checkout occur?
- how many checkouts fail and are never retried by the user?

If so, then you could create a separate resource:

POST /carts/<id>/checkOuts

As to your other point, it is perfectly normal for an apparently simple API call to have enormous side effects, e.g.:

DELETE /products/<id>

And indeed this can wreak havoc on things like your caching.

Felix Schäfer

unread,
Feb 3, 2015, 5:29:17 PM2/3/15
to api-...@googlegroups.com
Hi Andrew, thanks for your reply,

On Tue, Feb 3, 2015 at 8:46 PM, Andrew Braae <abr...@talentappstore.com> wrote:
>
> Do you care about the history of "checkouts" for a cart?
>
> e.g.:
> - how many fail due to credit card failures?
> - how long after first loading up the cart does the checkout occur?
> - how many checkouts fail and are never retried by the user?

None of that. The balance is managed in the app itself, and can be loaded upfront in cash, so there's no external dependency really.

> As to your other point, it is perfectly normal for an apparently simple API call to have enormous side effects, e.g.:
> DELETE /products/<id>

I see your point, though in that case I have a "dramatic" change to the product and side effects.

Effecting the payment by changing some internal state in the cart (status from "open" to "paid" or paid_for from "true" to "false") feels too much like talking to a "dumb" data store, where I'd have to also manually reduce the balance of the user and number of available products.

On the other hand, just POSTing to a /carts/<id>/pay also feels like a "dumb" RPC call.

Maybe my problem is also just so simple that the design/implementation will feel kinda dumb/simple :-)

Thanks for your input, I'm curious to hear what others think.

Felix

Shelby Switzer

unread,
Feb 4, 2015, 11:20:58 AM2/4/15
to api-...@googlegroups.com

The state of the cart and what that entails seems to me to be internal business logic that doesn’t need to be exposed through the API. I would probably just have an endpoint POST “/payments” and in the payload send the cart_id as part of the resource being POSTed. 

Simple example in JSON API format:
POST /payments
{ "payments": { "cart_id": 324, "amount": 100, "payment_method": "cash" } }

Reply all
Reply to author
Forward
0 new messages