Last active
February 5, 2024 23:38
-
-
Save jgdev/c5fa07986f77e2d34260c17941ace2ae to your computer and use it in GitHub Desktop.
Implementación CardNet Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from myapp.settings.base import API_BASE_URL, PAYMENTS_MERCHANT_NAME, PAYMENTS_MERCHANT_NUMBER, PAYMENTS_MERCHANT_TERMINAL, PAYMENTS_MCC | |
from myapp_payments.models import Transaction | |
from django.utils.translation import gettext as _ | |
class CardNetPaymentIntegrationService: | |
def get_message_from_status_code(status_code): | |
match status_code: | |
case "success": | |
return _("Success") | |
case "call_bank_entity": | |
return _("Call bank entity") | |
case "invalid_merchant": | |
return _("Invalid merchant") | |
case "transaction_rejected": | |
return _("Transaction rejected") | |
case "error_message": | |
return _("Error message") | |
case "card_rejected": | |
return _("Card rejected") | |
case "request_in_progress": | |
return _("Request in progress") | |
case "partial_approvation": | |
return _("Partial approvation") | |
case "invalid_transaction": | |
return _("Invalid transaction") | |
case "invalid_account": | |
return _("Invalid account") | |
case "invalid_amount": | |
return _("Invalid amount") | |
case "not_such_issuer": | |
return _("No such issuer") | |
case "customer_cancellation": | |
return _("Customer cancellation") | |
case "customer_dispute": | |
return _("Customer dispute") | |
case "retry_transaction": | |
return _("Retry transaction") | |
case "no_action_taken": | |
return _("No action taken") | |
case "transaction_not_approved": | |
return _("Transaction not approved") | |
case "transaction_not_accepted": | |
return _("Transaction not accepted") | |
case "duplicated_record": | |
return _("Duplicated record") | |
case "partially_completed": | |
return _("Partially completed") | |
case "card_expired": | |
return _("Card expired") | |
case "invalid_card": | |
return _("Invalid card") | |
case "insufficient_funds": | |
return _("Insufficient funds") | |
case "transaction_not_permitted": | |
return _("Transaction not permitted") | |
case "withdrawal_limit_exceeded": | |
return _("Withdrawal limit exceeded") | |
case "restricted_card": | |
return _("Restricted card") | |
case "rejected": | |
return _("Rejected") | |
case "pin_invalid": | |
return _("Pin invalid") | |
case "pin_required": | |
return _("Pin required") | |
case "cvv_or_cvc_error": | |
return _("Cvv or cvc error") | |
case _: | |
return _("Unexpected error") | |
def get_status_from_response_code(response_code): | |
match response_code: | |
case "00": | |
return Transaction.TRANSACTION_STATUS_SUCCESS | |
case "04" | "05" | "07" | "51" | "79" | "22" | "23" | "33" | "79": | |
return Transaction.TRANSACTION_STATUS_REJECTED | |
case _: | |
return Transaction.TRANSACTION_STATUS_ERROR | |
def get_details_from_response_code(response_code): | |
match response_code: | |
case "00": | |
return "success" | |
case "01" | "02" | "08": | |
return "call_bank_entity" | |
case "03": | |
return "invalid_merchant" | |
case "04" | "05": | |
return "transaction_rejected" | |
case "06": | |
return "error_message" | |
case "07": | |
return "card_rejected" | |
case "09": | |
return "request_in_progress" | |
case "10": | |
return "partial_approvation" | |
case "12": | |
return "invalid_transaction" | |
case "13": | |
return "invalid_amount" | |
case "14" | "42" | "52" | "53" | "56": | |
return "invalid_account" | |
case "15": | |
return "not_such_issuer" | |
case "17": | |
return "customer_cancellation" | |
case "18": | |
return "customer_dispute" | |
case "19": | |
return "retry_transaction" | |
case "20" | "21": | |
return "no_action_taken" | |
case "22" | "34" | "35" | "36" | "37" | "38" | "41" | "43": | |
return "transaction_not_approved" | |
case "23": | |
return "transaction_not_accepted" | |
case "26" | "94": | |
return "duplicated_record" | |
case "32": | |
return "partially_completed" | |
case "33": | |
return "card_expired" | |
case "39" | "54": | |
return "invalid_card" | |
case "51": | |
return "insufficient_funds" | |
case "57" | "58": | |
return "transaction_not_permitted" | |
case "61": | |
return "withdrawal_limit_exceeded" | |
case "62": | |
return "restricted_card" | |
case "79": | |
return "rejected" | |
case "81": | |
return "pin_invalid" | |
case "82": | |
return "pin_required" | |
case "99": | |
return "cvv_or_cvc_error" | |
case _: | |
return "unexpected_error" | |
def get_payment_authorization_response(data: dict): | |
response_code = data.get("ResponseCode") | |
authorization = data.get("AuthorizationCode") | |
response_code_details = ( | |
CardNetPaymentIntegrationService.get_details_from_response_code( | |
response_code | |
) | |
) | |
status_code = CardNetPaymentIntegrationService.get_status_from_response_code( | |
response_code | |
) | |
message = CardNetPaymentIntegrationService.get_message_from_status_code(response_code_details) | |
return ( | |
status_code, | |
data.get("OrderId"), | |
data.get("TransactionID"), | |
response_code_details, | |
message, | |
authorization | |
) | |
def get_payment_authorization_params( | |
transaction: Transaction, | |
reference: str, | |
client_ip: str, | |
payment_integration_type: str, | |
tx_type: str, | |
): | |
if transaction.currency != "USD" and transaction.currency != "DOP": | |
raise Exception("Currency %s not supported" % transaction.currency) | |
return { | |
"TransactionType": "0200", | |
"Amount": transaction.amount * 100, | |
"Tax": transaction.tax * 100, | |
"CurrencyCode": 214 | |
if transaction.currency == "DOP" | |
else 840, # DOP=214, USD=840 | |
"MerchantName": PAYMENTS_MERCHANT_NAME, | |
"MerchantNumber": PAYMENTS_MERCHANT_NUMBER, | |
"MerchantTerminal": PAYMENTS_MERCHANT_TERMINAL, | |
"MerchanType": PAYMENTS_MCC, | |
"ReturnUrl": "%s/v1/payments/transactions/check_transaction/?payment_integration_type=%s&tx_type=%s" | |
% (API_BASE_URL, payment_integration_type, tx_type), | |
"CancelUrl": "%s/v1/payments/transactions/reject/" % API_BASE_URL, | |
"PageLanguaje": "en", | |
"TransactionId": reference, | |
"KeyEncriptionKey": "1fc500b127d04b532f759d183944b057", | |
"Ipclient": client_ip, | |
"AcquiringInstitutionCode": "349", | |
"OrdenID": transaction.id, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require('http') | |
const url = 'http://localhost:3000'; | |
const server = http.createServer((req, res) => { | |
if (req.method === 'GET' && req.url === '/') { | |
res.setHeader('Content-Type', 'text/html') | |
res.write(`<form action="https://lab.cardnet.com.do/authorize" method="POST"> | |
<input name="TransactionType" value="0200" type="hidden" /> | |
<input name="Amount" value="55000.00" type="hidden"/> | |
<input name="Tax" value="0.00" type="hidden"/> | |
<input name="CurrencyCode" value="214" type="hidden"/> | |
<input name="MerchantName" value="COMERCIO PARA REALIZAR PRUEBAS DO" type="hidden"/> | |
<input name="MerchantNumber" value="349000000" type="hidden"/> | |
<input name="MerchantTerminal" value="58585858" type="hidden"/> | |
<input name="MerchanType" value="7997" type="hidden"/> | |
<input name="ReturnUrl" value="${url}/v1/payments/transactions/check_transaction/?payment_integration_type=credit_card&tx_type=leads" type="hidden"/> | |
<input name="CancelUrl" value="${url}/v1/payments/transactions/reject/" type="hidden"/> | |
<input name="PageLanguaje" value="en" type="hidden"/> | |
<input name="TransactionId" value="2HJUSD" type="hidden"/> | |
<input name="KeyEncriptionKey" value="1fc500b127d04b532f759d183944b057" type="hidden"/> | |
<input name="Ipclient" value="134.209.169.7" type="hidden"/> | |
<input name="AcquiringInstitutionCode" value="349" type="hidden"/> | |
<input name="OrdenID" value="a5a7e92e-a1d6-4e46-ad9e-38758756e9f7" type="hidden"/> | |
<button>Make payment</button> | |
</form>`) | |
res.statusCode = 200; | |
} else if (req.method === "POST") { | |
let data; | |
req.on('data', d => { | |
if (!data) data = d | |
else data += d | |
}) | |
req.on('end', () => { | |
console.log('CardNet response', data.toString('utf8')) | |
res.setHeader('Content-Type', 'text/html') | |
res.write('<a href="/">Go back</a>'); | |
res.statusCode = 200 | |
}) | |
} else { | |
res.setHeader('location', '/') | |
} | |
}) | |
server.listen(3000, () => { | |
console.log(`Server ready at: ${url}`) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment