Skip to content

Commit

Permalink
#64 move 'charge' transactions to 'authorization' transactions accord…
Browse files Browse the repository at this point in the history
…ing to the adyen best practices. (#85)

* add details for checkout steps.

* update Charge to Authorization.

* Update extension/docs/IntegrationGuide.md

Co-Authored-By: andreas Halberkamp <andreas.halberkamp@commercetools.de>

* Update extension/docs/IntegrationGuide.md

Co-Authored-By: andreas Halberkamp <andreas.halberkamp@commercetools.de>

* Link integration guide with Refund/Cancel guide #71

* additional unit test for the manual capture cases

* add additional integration test for manual capture notification

* Split unit and integration test commands (#82)

* bump version to 3.0.0

* Update extension/docs/IntegrationGuide.md

Co-Authored-By: Roman Butenko <roman.butenko@commercetools.de>

* Update extension/docs/IntegrationGuide.md

Co-Authored-By: Roman Butenko <roman.butenko@commercetools.de>

* Update extension/docs/IntegrationGuide.md

Co-Authored-By: Roman Butenko <roman.butenko@commercetools.de>

* Update extension/docs/IntegrationGuide.md

Co-Authored-By: Roman Butenko <roman.butenko@commercetools.de>

* Update notification/test/unit/notification.handler.spec.js

Co-Authored-By: Hasan <LEQADA@users.noreply.github.com>

* add quotes for the adyen events.

* add nyc to integration tests.

* revert changes for test command.

* add explanation for why originalReference should use the AUTHORIZATION notification event.

* make cancel or refund documentation more clear.

* handle the cancel or refund notification correctly on notification module.
  • Loading branch information
ahmetoz committed Dec 10, 2019
1 parent f5d0231 commit 77f9cba
Show file tree
Hide file tree
Showing 35 changed files with 1,429 additions and 172 deletions.
10 changes: 6 additions & 4 deletions extension/docs/CancelRefundPayment.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@
]
}
```
Both transaction types work the same, because Adyen will always pick the right action for the current transaction.
If the transaction is not authorized yet, Adyen will try to cancel.
If the transaction is already charged, Adyen will do refund.
1. In `Payment.transactions`, extension module finds the first transaction with `type='Charge' and state='Success'`.

- Both transaction types work the same, because Adyen will always pick the right action for the current transaction.
- This will either:
- Cancel the payment – in case it has not yet been captured.
- Refund the payment – in case it has already been captured.
1. In `Payment.transactions`, extension module finds the first transaction with `type='Authorization' and state='Success'`.
Extension module takes `amount` and `transactionId` from this transaction and makes a 'Cancel or refund' request.
1. Extension module saves following information to the payment object:
* `Payment.interfaceInteractions` with `type='cancelOrRefund'` that contains request and response with Adyen
Expand Down
12 changes: 6 additions & 6 deletions extension/docs/CreditCardIntegration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The following features are not supported:
### Credit card
1. Shop collects shopper details according to the [Adyen documentation](https://docs.adyen.com/developers/payment-methods/cards-with-3d-secure#step1collectshopperdetails) and creates a payment with following criteria ([Example payment](../test/fixtures/payment-credit-card.json)):
* `Payment.paymentMethodInfo.method = 'creditCard'`
* `Payment.transactions` contains a transaction with `type='Charge' and state='Initial'`
* `Payment.transactions` contains a transaction with `type='Authorization' and state='Initial'`
* `Payment.custom.fields.encryptedCardNumber` contains credit card number encrypted in the previous step.
* `Payment.custom.fields.encryptedExpiryMonth` contains expiry month encrypted in the previous step.
* `Payment.custom.fields.encryptedExpiryYear` contains expiry year encrypted in the previous step.
Expand All @@ -30,7 +30,7 @@ The following features are not supported:
* *Optional*: `paymentObject.custom.fields.holderName`
1. Extension module makes a payment request and save following information to the payment object:
* `Payment.interfaceInteractions` with `type='makePayment'` that contains request and response with Adyen
* `Payment.transactions` with a transaction `type='Charge' and state='Initial'` will be changed to a new state according to [the returned result code](./IntegrationGuide.md#mapping-from-adyen-result-codes-to-ctp-transaction-state).
* `Payment.transactions` with a transaction `type='Authorization' and state='Initial'` will be changed to a new state according to [the returned result code](./IntegrationGuide.md#mapping-from-adyen-result-codes-to-ctp-transaction-state).
* `pspReference` will be saved in a matching transaction from the previous point in a field `Payment.transactions.interactionId`
1. Shop validates the payment and presents the payment result to the shopper.

Expand All @@ -39,7 +39,7 @@ The following features are not supported:
### Credit card with 3D Secure
1. Shop collects shopper details according to the [Adyen documentation](https://docs.adyen.com/developers/payment-methods/cards-with-3d-secure#step1collectshopperdetails) and creates a payment with following criteria ([Example payment](../test/fixtures/payment-credit-card-3d.json)):
* `Payment.paymentMethodInfo.method = 'creditCard_3d'`
* `Payment.transactions` contains a transaction with `type='Charge' and state='Initial'`
* `Payment.transactions` contains a transaction with `type='Authorization' and state='Initial'`
* `Payment.custom.fields.encryptedCardNumber` contains credit card number encrypted in the previous step.
* `Payment.custom.fields.encryptedExpiryMonth` contains expiry month encrypted in the previous step.
* `Payment.custom.fields.encryptedExpiryYear` contains expiry year encrypted in the previous step.
Expand All @@ -49,7 +49,7 @@ The following features are not supported:
* *Optional*: `paymentObject.custom.fields.holderName`
1. Extension module makes a payment request and save following information to the payment object (for explanation of each field, see [Adyen's documentations](https://docs.adyen.com/developers/payment-methods/cards-with-3d-secure#step2makeapayment)):
* `Payment.interfaceInteractions` with `type='makePayment'` that contains request and response with Adyen
* `Payment.transactions` with a transaction `type='Charge' and state='Initial'` will be changed to `state='Pending'`.
* `Payment.transactions` with a transaction `type='Authorization' and state='Initial'` will be changed to `state='Pending'`.
* `Payment.custom.fields.MD`
* `Payment.custom.fields.PaReq`
* `Payment.custom.fields.paymentData`
Expand All @@ -69,7 +69,7 @@ The following features are not supported:
```
1. Extension module makes a [payment request](https://docs.adyen.com/developers/payment-methods/cards-with-3d-secure#step4completepayment) and save following information to the payment object:
* `Payment.interfaceInteractions` with `type='completePayment'` that contains request and response with Adyen
* `Payment.transactions` with a transaction `type='Charge' and state='Pending'` will be changed to a new state according to [the returned result code](IntegrationGuide.md#mapping-from-adyen-result-codes-to-ctp-transaction-state).
* `Payment.transactions` with a transaction `type='Authorization' and state='Pending'` will be changed to a new state according to [the returned result code](IntegrationGuide.md#mapping-from-adyen-result-codes-to-ctp-transaction-state).
* `pspReference` will be saved in a matching transaction from the previous point in a field `Payment.transactions.interactionId`
1. Shop validates the payment and presents the payment result to the shopper.

Expand All @@ -78,4 +78,4 @@ The following features are not supported:
![3D Secure flow](https://user-images.githubusercontent.com/803826/56141166-93c1cf80-5f9c-11e9-88f4-95a694ad4227.png)

### Other
Please consult [Adyen documentation](https://docs.adyen.com/developers/payment-methods/cards) for additional information.
Please consult [Adyen documentation](https://docs.adyen.com/developers/payment-methods/cards) for additional information.
11 changes: 7 additions & 4 deletions extension/docs/IntegrationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ In this process, there are 3 parties involved:
- **Shopper** - a person that's using the shop

Other used terms in the documentation:
- **Cancel** - cancel the authorisation on an uncaptured payment.
- **Refund** - refund a payment back to the shopper.
- [**Cancel**](CancelRefundPayment.md#cancel-or-refund-a-payment) - cancel the authorisation on an uncaptured payment.
- [**Refund**](CancelRefundPayment.md#cancel-or-refund-a-payment) - refund a payment back to the shopper.


## Requirements for CTP project
All the requirements below are automatically created by the Extension module.
Expand Down Expand Up @@ -63,12 +64,14 @@ If all above validations are passed then order can be created right away and ord
Otherwise shopper might continue with further payment steps.

1. **Get available payment methods**
> Before user can proceed with particular payment method below steps describes how to get and present the list of available payment methods:
1. [Create/update a CTP Payment](https://docs.commercetools.com/http-api-projects-payments) with following properties:
- `Payment.paymentMethodInfo.method = empty or undefined`
- `Payment.custom.fields.countryCode != null` - set the country of a shopper. Please [consult with Adyen](https://docs.adyen.com/api-explorer/#/PaymentSetupAndVerificationService/v41/paymentMethods) for the right format.
1. Extension module will make a [request](https://docs.adyen.com/checkout/api-integration/#step-1-get-available-payment-methods) to Adyen API and the response will be saved in interface interaction with `type='ctp-adyen-integration-interaction'` and `fields.type='getAvailablePaymentMethods'` as stringified JSON.
1. Before presenting the payment methods in the response from Adyen, please check Extension module documentation for supported payment methods.
1. **Continue with one of the supported payment methods**
> Below guides describe how to handle different type of payment methods selected by the user:
- [Credit card payment](./CreditCardIntegration.md)
- [Paypal payment](./PaypalIntegration.md)

Expand Down Expand Up @@ -107,8 +110,8 @@ The combination of `Payment.custom.fields.merchantReference` and `Payment.paymen

### Validate payment transaction
Cart's payment counts as successful if there is at least one payment object
with only successful (`Payment.Transaction.state=Success`)
payment transactions of type `Charge`.
with successful transaction state (`Payment.Transaction.state=Success`)
and transactions type `Authorization` or `Charge`.

### Mapping from Adyen result codes to CTP transaction state
|Adyen result code| CTP transaction state
Expand Down
4 changes: 2 additions & 2 deletions extension/docs/KcpIntegration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
1. Contact Adyen to enable KCP
1. Shop creates a payment with following criteria:
* `Payment.paymentMethodInfo.method = 'kcp_creditcard' OR payment.paymentMethodInfo.method = 'kcp_banktransfer'`
* `Payment.transactions` contains a transaction with `type='Charge' and state='Initial'`
* `Payment.transactions` contains a transaction with `type='Authorization' and state='Initial'`
* `Payment.custom.fields.returnUrl` contains return URL to which the shopper will be redirected after completion.
1. Extension module makes a `Redirect shopper` request and saves following information to the payment object:
* `Payment.interfaceInteractions` with `type='makePayment'` that contains request and response with Adyen
* `payment.custom.fields.redirectUrl`
* `payment.custom.fields.redirectMethod`
* `Charge` transaction state will be updated to `Pending`
* `Authorization` transaction state will be updated to `Pending`
1. Shop redirects user to KCP using the custom fields above

**TODO: to be continued**
8 changes: 4 additions & 4 deletions extension/docs/PaypalIntegration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
1. [Enable Paypal in Adyen](https://docs.adyen.com/developers/payment-methods/paypal#prerequisites)
1. Shop creates a payment with following criteria ([Example payment](../test/fixtures/payment-paypal.json)):
* `Payment.paymentMethodInfo.method = 'paypal'`
* `Payment.transactions` contains a transaction with `type='Charge' and state='Initial'`
* `Payment.transactions` contains a transaction with `type='Authorization' and state='Initial'`
* `Payment.custom.fields.returnUrl` contains return URL to which the shopper will be redirected after completion.
1. Extension module make a payment request and save following information to the payment object:
* `Payment.interfaceInteractions` with `type='makePayment'` that contains request and response with Adyen
* `Payment.transactions` with a transaction `type='Charge' and state='Initial'` will be changed to `'Pending'`.
* `Payment.transactions` with a transaction `type='Authorization' and state='Initial'` will be changed to `'Pending'`.
* `Payment.custom.fields.redirectUrl`
* `Payment.custom.fields.redirectMethod`
1. Shop [redirects shopper](https://docs.adyen.com/developers/payment-methods/paypal#step2redirectshopper) to Paypal.
Expand All @@ -33,12 +33,12 @@
```
1. Extension module make a [payment request](https://docs.adyen.com/developers/payment-methods/paypal#step4presentpaymentresult) and save following information to the payment object:
* `Payment.interfaceInteractions` with `type='completePayment'` that contains request and response with Adyen
* `Payment.transactions` with a transaction `type='Charge' and state='Pending'` will be changed to a new state according to [the returned result code](IntegrationGuide.md#mapping-from-adyen-result-codes-to-ctp-transaction-state).
* `Payment.transactions` with a transaction `type='Authorization' and state='Pending'` will be changed to a new state according to [the returned result code](IntegrationGuide.md#mapping-from-adyen-result-codes-to-ctp-transaction-state).
* `pspReference` will be saved in a matching transaction from the previous point in a field `transactionInteractionId`
1. Shop validates the payment and presents the payment result to the shopper.

*Notice*: the last step of Extension module is mandatory but it doesn't play any significant role for Adyen.
Funds has already been reserved/transferred after the shopper confirms payment on Paypal. Nevertheless, it's important
to follow all the steps as it's the only way to get `pspReference` from Adyen.

![Paypal flow](https://user-images.githubusercontent.com/803826/56141239-b9e76f80-5f9c-11e9-95e7-7358903121cd.png)
![Paypal flow](https://user-images.githubusercontent.com/803826/56141239-b9e76f80-5f9c-11e9-95e7-7358903121cd.png)

0 comments on commit 77f9cba

Please sign in to comment.