I am unable to find when to expect processor response code "2016 Duplicate Transaction"? only when previously a similar transaction was successful ? or when processor has seen this transaction recently (even if it failed). in contrast to gateway rejection for duplicate transaction, which only happens when a previous similar transaction was successful. thanks.
I work at Braintree. If you have more questions, you can always reach out to our support team.
I originally misunderstood your question. Processors don't necessarily provide the specifics as to why they return a particular processor response. Your best bet is to reach out to Braintree support and see if they can provide any more information in this particular case.
My original answer about Braintree duplicate transaction checking follows.
A transaction will be rejected as a duplicate when you have the duplicate checking option enabled and the following conditions are met:
Credit Card Number is the same
Credit Card Expiration Date is the same
Amount is the same
Order ID is the same OR Subscription ID is the same
Previous transaction was within X seconds (30 by default)
Previous transaction was successful
Related
We're trying to understand how to compensate a "saga compensation failure".
We have two microservices, and two databases, one per microservice.
Customer microservice
Contract microservice
Use case: Customer alias modification.
Request is sent to "Customer microservice".
a. Customer alias is modified on customer table, but its state is pending.
b. A customer modified event is sent.
customer modified event is received by "Constract microservice".
a. Received Customer is updated on all contracts (we're using mongodb), since customer information is embedded in each contract.
b. A contract updated event is sent.
contract updated event is received by "Customer microservice".
a. Customer's state is set to confirmed.
If 3.a fails a compensation action is performed, but what about if it fails?
This can be handle with combination of below approaches:
Implement Retry pattern for Compensate Action
Exception handling - exception can be save and, this can be resolve through - Automated process like Retry mechanism through separate application
This is extension of approach#2, If Automated process unable to resolve, generate exception report which can be review manually and action can be taken based on the issue.
It looks like you are using the term saga but you really mean you want a transaction. If you really need a transaction do that (you can look at solutions like https://docs.temporal.io/ for providing that)
[personally I think transactions between services are bad, and if I need transaction between services, I try to rethink my design but your milage may vary]
You didn't specify the reason on why contracts would reject the change - if there are business rules that one thing but if these are "technical reasons" like availability etc. then the thing to do is to make sure the event is persistent and was sent (e.g. like outbox pattern on the sending side) and have the consuming service(s) handle it when it can
If there are business rules involved then maybe it is a bad example but I'd expect a person can still change their alias regardless and the compensation would be keeping some of the contracts with the old alias or something a long these lines.
by the way, it seems you have a design issue that causes needless temporal coupling between your services.
If the alias is important in contracts but owned by the customers service, the alias stored in the contracts should be considered as cached.
In this case the customers service can close the update regardless of what other services do. it can fire the event and you can complete the process when you can on the contracts service. when a contract is read you can check if there's a newer version of the customer and if so get it. you may also (depending on the business reqs. specify that the data is correct as of the last update)
BASE VS ACID :
ISOLATION: As local transactions are committed while the Saga is running, their changes are already visible to other concurrent transactions, despite the possibility that the Saga will fail eventually, causing all previously applied transactions to be compensated. I.e., from the perspective of the overall Saga, the isolation level is comparable to “read uncommitted.”
Eventually other services will read those inconsistent events, they will also take wrong decisions according to these, they will increase the number of events which should not be happen at all.
In the end there will be tons of events to rollback (how is that possible if your system let users to do more than allowed in real world ? Can you get back an ice cream from a kid which is sold 5 minute ago !)
For the last few weeks or so, we are having the following issue:
Some of our transactions, when sent via sendRawTransaction() never get picked up by the network (if we look up the txid in the explorer, it's never there), and yet web3js doesn't error out.
We use "#solana/web3.js": "^1.44.1"
This has started happening to us like 2-3 weeks ago:
This issue affects some sets of transactions that all share the same instructions + amount of signers and accounts.
It repros 100% of the time for all transactions in those sets. No matter the state of the network or how many times we retry, they never get picked up.
We don't get any error back from web3.js, such as transaction limit hit
They all work in devnet, but not in mainnet!
For one of these tx, I removed one instruction+signer and it started working, so I imagine there's some limit we're hitting, but I can't tell which or how to even determine the limit.
When network congestion is high, validators can drop transactions without any error. To fix your issue you could send more of the same transaction on some interval while you're waiting for confirmation, and while your transaction blockhash is valid. This way you'll raise a chances for your transaction to been processed by the validator.
I submit a transaction with a valid card but I make it trigger a "Decline" from RiskData by making a lot of transactions with that card quickly. The problem is that it still makes the transaction successful and submits it for settlement even when RiskData returns "Decline".
Here is what Braintree has regarding a "Decline" RiskData:
'Decline' - The transaction was declined due to fraud risk.
Is this how it's supposed to function? Should I change the configuration to make it reject a transaction for "Decline"?
Here is some reference:
#<Braintree::SuccessfulResult transaction:#<Braintree::Transaction id: "xxxxx"...>
#<RiskData id: "xxxxxxxxx", decision: "Decline">
I work at Braintree. If you have more questions, please reach out to our support team.
In Sandbox, Braintree doesn't act on the risk decision, so this is expected behavior if you aren't using the fraud rejection card number.
In production, "Decline" RiskData will cause transactions to be rejected; "Review" RiskData will not. It's unlikely you'll ever see a status of "Review" in production unless you obtain your own merchant ID with Kount directly and set your own rules to trigger this response.
I can see that the capture has been processed successfully:
But then on the "transactions" screen, "Is Closed" column is saying "no" next to capture. I think I just don't understand the role of this column. Can someone help explain it to me?
A little background on the credit card payment transaction process flow helps make sense of this. These are the basic flow actions of the transaction lifecycle:
Authorization
Capture
Settlement
These flow actions are broken down into more specific operations that can be called against the payment gateway. Here are some basic ones that are relevant:
Authorize (AUTH_ONLY):
Run the card for a given amount and obtain a unique authorization code. The amount will be put on hold and you are guaranteed these funds as long as you use the authorization code in a Capture transaction within 30 days. (How long before an authorization code expires varies by company. Check with your payment gateway)
Customers don't see the authorization as a charge on their statement, but they will see their available funds decrease by the amount you ran the authorization for.
If you don't use the authorization code in a follow-up Capture transaction, the authorization is "dropped", funds returned to the customer's balance and you can no longer use it.
Capture (PRIOR_AUTH_CAPTURE):
Use a previously obtained authorization code to complete the transaction.
The amount captured can be lower than the originally obtained authorization amount (this is useful in cases like our example where you don't know the total order amount ahead of time).
Source: http://www.softwareprojects.com/resources/conversion-traffic-to-cash/t-processing-payments-authorize-vs-capture-vs-settle-2030.html
Settlement: This is the process merchants must complete ... to be paid for their transactions.
The product or service must be delivered or performed before settlement can take place. In the case of mail order/telephone order, this specifically means the goods must be shipped before the settlement process is performed.
Source: http://www.shift4.com/insight/glossary/
In Magento, the is_closed flag signifies that a transaction is settled and no other operations may be performed against it. The reason a transaction would be left open until settlement is so that you can do partial shipments of goods (multiple captures), as well as void or refund the transaction.
To use Magento’s Mage_Authorizenet_Model_Directpost as an example, the capture() operation leaves the current transaction open, while void() and _refund() operations close it.
Is there a RESTful way to determine whether a POST (or any other non-idempotent verb) will succeed? This would seem to be useful in cases where you essentially need to do multiple idempotent requests against different services, any of which might fail. It would be nice if these requests could be done in a "transaction" (i.e. with support for rollback), but since this is impossible, an alternative is to check whether each of the requests will succeed before actually performing them.
For example suppose I'm building an ecommerce system that allows people to buy t-shirts with custom text printed on them, and this system requires integrating with two different services: a t-shirt printing service, and a payment service. Each of these has a RESTful API, and either might fail. (e.g. the printing company might refuse to print certain words on a t-shirt, say, and the bank might complain if the credit card has expired.) Is there any way to speculatively perform these two requests, so my system will only proceed with them if both requests appear valid?
If not, can this problem be solved in a different way? Creating a resource via a POST with status = pending, and changing this to status = complete if all requests succeed? (DELETE is more tricky...)
HTTP defines the 202 status code for exactly your scenario:
202 Accepted
The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.
The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.
Source: HTTP 1.1 Status Code Definition
This is similar to 201 Created, except that you are indicating that the request has not been completed and the entity has not yet been created. Your response would contain a URL to the resource representing the "order request", so clients can check the status of the order through this URL.
To answer your question more directly: There is no way to "test" whether a request will succeed before you make it, because you're asking for clairvoyance.
It's not possible to foresee the range of technical problems that could occur when you attempt to make a request in the future. The network may be unavailable, the server may not be able to access its database or external systems it depends on for functioning, there may be a power-cut and the server is offline, a stray neutrino could wander into your memory and bump a 0 to a 1 causing a catastrophic kernel fault.
In order to consume a remote service you need to account for possible failures of any request in isolation of any other processes.
For your specific problem, if the services have no transactional safety, you can't bake any in there and you have to deal with this in a more real-world way. A few options off the top of my head:
Get the T-Shirt company to give you a "test" mechanism, so you can see whether they'll process any given order without actually placing it. It could be that placing an order with them is a two-phase operation, where you construct the order in the first phase (at which time they validate its creation) and then you subsequently ask the order to be processed (after you have taken payment successfully).
Take the credit-card payment first and move your order into a "paid" state. Then attempt to fulfil the order with the T-Shirt service as an asynchronous process. If fulfilment fails and you can identify that the customer tried to get something printed the company is not prepared to produce, you will have to contact them to change their order or produce a refund.
Most organizations will adopt the second approach, due to its technical simplicity and reduced risk to the business. It also has the benefit of being able to cope with the T-Shirt service not being available; the asynchronous process simply waits until the service is available and completes the order at that time.
Exactly. That can be done as you suggest in your last sentence. The idea would be to decopule resource creation (that will always work unless network failures) that represents an "ongoing request" of the "order acceptation", that can be later decided. As POST returns a "Location" header, you can then retrieve in any moment the "status" of your request.
At some point it may become either accepted or rejected. This may be intantaneous or it may take some time, so you have to design your service with these restrictions (i.e. allowing the client to check if his/her order is accepted, or running some kind of hourly/daily service that collect accepted requests).