VAT Refund Integration¶
Jumpmind Commerce supports extending the IVatRefundService through Microservice Endpoint
implementations which allow VAT refund customers to be maintained in a separate system from Jumpmind Commerce.
VAT Refund supports multiple providers which implement the shared IVatRefundService interface. In general all provider
specific requirements should be delegated to their specific VatRefund service implementation (i.e. planet, duty-blue, etc.).
Otherwise, the flow in Commerce should be the same across providers and only require configuration to work.
Setup VAT Refund¶
To opt-into VAT Refund there are several steps required to configure and call the service integration:
1. Specify the VAT Refund provider in the service configuration (i.e. simulated, planet, etc.)
2. Configure the provider form in post_00_ctx-form.csv in the vatRefund form group
3. Configure the provider form fields in post_00_ctx-form-field.csv and add any required translations in the customer.properties localization files
> Note: Be sure to have fields align with PII filters (see PII)
4. Update the translations in sales.properties for displaying the form title and instructions as well as the displayed line item.
5. Include any new provider logos in the receipt-images/vat-refund-logos with the format providerName-logo.png.
6. Update the receipt.properties to include the correct language on the receipt.
7. Update the post_00_ctx-button.csv file to ensure the VatRefund buttons are tagged for the appropriate country
8. Ensure the country jurisdiction has VAT tax rules configured for the desired country.
>NOTE: A VAT tax rule is considered as a rule with the VAT_PERCENT rule type and the tax is included in the line item price.
9. Finally add a new VatRefund service implementation for the provider as needed
Using VAT Refund¶
VAT Refunds can be opted-into during a transaction or after the fact by linking the refund to the transaction.
Note that if the transaction is returned (or voided), the previously submitted transaction MUST be cancelled prior to submitting an updated transaction to the provider.
Add VAT Refund to current Sale¶
After a sale session has begun and there is an active transaction, the cashier can ask the shopper if they would like to
opt-into a VAT refund. If they accept, the cashier can select the sale.transaction.active.VatRefund option from the menu.
After filling in the details, a line item with the text in screen.itemType.label.vatRefund will be added to the transaction.
After completing the transaction, a request to the provider will be submitted and the returned details will be populated
on the receipt.
Add VAT Refund to prior Sale¶
After a sale has completed, it is still possible for a shopper to opt into VAT refunds. The cashier can go to the transaction
search screen and select the action with the screen.search.label.vatRefund translation. From there the cashier can enter
the shopper details and submit the transaction to the provider. From there a vat-refund-link-chit is printed containing
just the VAT refund details from the provider.
Key Points¶
It is also important to note that when linking a VAT refund to a prior transaction, we create a new
SLS_VAT_REFUND_TRANS pointing to the original transaction. This ensures the VAT refund doesn't modify the transaction
we link against. This requires checking both for the line item or the linked transaction for any logic that checks for a
VAT refund.
PII Sensitivity¶
Even though we collect shopper PII details as part of the VAT refund flow, those details are NEVER to persist in
the database or logs. It is important to ensure that the new SLS_VAT_REFUND_LINE_ITEM, SLS_VAT_REFUND_TRANS, or
PUB_PAYLOAD tables never contains PII.
For the logging requirements, we can ensure logs do not contain PII by aligning the vatRefund form group fields
use the same names as listed in the LogUtils.SENSITIVE_FIELDS. This will ensure the HttpLoggerInterceptor will mask the PII fields
when in Production (masking is disabled during Development).
Provider Specific Configurations¶
This section outlines configuration used by each provider implementation.
Note: that these configurations should exist under
openpos.services.vatRefund
Planet Configuration¶
| Config | Description | Default |
|---|---|---|
| planet.clientId | The client id used to OAuth with Planet.Provided by Planet |
-- |
| planet.clientSecret | The client secret used to OAuth with Planet.Provided by Planet |
-- |
| planet.terminal | The terminal to associate this transaction against. Provided by Planet |
-- |
| planet.vatCode | The VAT code configured for Planet Provided by Planet |
-- |
| planet.merchandiseGroup | The merchandise group to submit the transaction under. Provided by Planet. |
-- |
| planet.minimumAge | The minimum age of the shopper to allow VAT refundEnforced by Planet |
18 |
| planet.minimumTransactionTotal | The minimum transaction total to allow VAT refundEnforced by Planet |
250.0 |
| planet.transactionUrl | The url to submit transactions. Provided by Planet |
-- |
| planet.cancelUrl | The url to cancel transactions. Provided by Planet |
-- |
| planet.tokenUrl | The url to retrieve an OAth token.Provided by Planet |
-- |
| planet.xsrfToken | The XSRF token to include in requests Provided by Planet |
-- |
Example¶
If a customer requires custom logic when building the requests for a particular provider it is possible to override the endpoint with a custom implementation and still leverage the existing provider client to actually submit the request.
@Slf4j
@Endpoint(path = REST_API_CONTEXT_PATH + "/vatRefund/transaction", implementation = "customPlanet")
@RequiredArgsConstructor
public class CustomPlanetSubmitTransactionEndpoint {
private final PlanetClient client;
public VatRefundSubmitTransactionResponse submitTransaction(VatRefundSubmitTransactionRequest request) {
SubmitTransactionRequest submitRequest = buildTransactionRequest(request);
return client.submitTransaction(submitRequest);
}
public SubmitTransactionRequest buildTransactionRequest(VatRefundSubmitTransactionRequest request) {
// customer specific logic can be built out here
return SubmitTransactionRequest.builder().build();
}
}