├── .gitignore ├── .idea ├── epayco-python.iml ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── MANIFEST.in ├── README.rst ├── epaycosdk ├── __init__.py ├── client.py ├── epayco.py ├── errors.py ├── resources.py ├── test │ └── __init__.py └── utils │ ├── __init__.py │ ├── key_lang.json │ └── key_lang_apify.json └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | #Ignore .pyc 2 | *.pyc 3 | 4 | #Ignore test.py 5 | test*.py 6 | 7 | #Ignore build 8 | build/* 9 | 10 | #Ignore dist 11 | dist/* 12 | 13 | #Ignore idea 14 | idea/* 15 | 16 | epaycosdk_win.egg-info 17 | epaycosdk.egg-info 18 | -------------------------------------------------------------------------------- /.idea/epayco-python.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 141 | 142 | 143 | 144 | build_url 145 | setKeys 146 | 147 | 148 | 149 | 151 | 152 | 162 | 163 | 164 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 192 | 193 | 196 | 197 | 200 | 201 | 202 | 203 | 206 | 207 | 210 | 211 | 212 | 213 | 216 | 217 | 220 | 221 | 224 | 225 | 226 | 227 | 230 | 231 | 234 | 235 | 238 | 239 | 242 | 243 | 244 | 245 | 248 | 249 | 252 | 253 | 256 | 257 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 293 | 294 | 305 | 306 | 324 | 325 | 343 | 344 | 364 | 365 | 386 | 387 | 410 | 411 | 412 | 414 | 415 | 416 | 417 | 1500510574042 418 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.py README.rst epaycosdk/utils/key_lang.json epaycosdk/utils/key_lang_apify.json 2 | recursive-include epaycosdk/*.* 3 | recursive-include epaycosdk/utils/*.* 4 | recursive-include epaycosdk/test/*.* -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ***** 2 | Epayco 3 | ***** 4 | 5 | Python wrapper for Epayco API 6 | 7 | Description 8 | ######## 9 | 10 | API to interact with Epayco 11 | https://api.epayco.co 12 | 13 | Installation 14 | **** 15 | Installation 16 | ============ 17 | 18 | If you want to clone the repository, point it directly into our GitHub project: 19 | 20 | .. code-block:: bash 21 | 22 | $ git clone https://github.com/epayco/epayco-python.git 23 | 24 | Install from Packages (Linux), Python = 3.7 25 | ------------------------------------------- 26 | 27 | Run the file `setup.py`: 28 | 29 | .. code-block:: bash 30 | 31 | $ sudo python3 setup.py install 32 | 33 | Install the ePayco module: 34 | 35 | .. code-block:: bash 36 | 37 | $ pip install epaycosdk 38 | 39 | Install from Packages (Windows), Python = 3.7 40 | --------------------------------------------- 41 | 42 | Run the file `setup.py`: 43 | 44 | .. code-block:: bash 45 | 46 | $ pip install setuptools 47 | $ python setup.py install 48 | 49 | Install the ePayco module: 50 | 51 | .. code-block:: bash 52 | 53 | $ pip install epaycosdk 54 | 55 | 56 | Usage 57 | #### 58 | 59 | .. code-block:: python 60 | 61 | import epaycosdk.epayco as epayco 62 | 63 | apiKey = "PUBLIC_KEY" 64 | privateKey = "PRIVATE_KEY" 65 | lenguage = "ES" 66 | test = True 67 | options={"apiKey":apiKey,"privateKey":privateKey,"test":test,"lenguage":lenguage} 68 | 69 | objepayco=epayco.Epayco(options) 70 | 71 | Create Token 72 | #### 73 | 74 | .. code-block:: python 75 | 76 | credit_info = { 77 | "card[number]": "4575623182290326", 78 | "card[exp_year]": "2025", 79 | "card[exp_month]": "19", 80 | "card[cvc]": "123", 81 | "hasCvv": True #// hasCvv: validar codigo de seguridad en la transacción 82 | } 83 | 84 | token=objepayco.token.create(credit_info) 85 | 86 | Customers 87 | #### 88 | 89 | Create 90 | ****** 91 | .. code-block:: python 92 | 93 | customer_info = { 94 | "token_card": "eXj5Wdqgj7xzvC7AR", 95 | "name": "Joe", 96 | "last_name": "Doe", #This parameter is optional 97 | "email": "joe@payco.co", 98 | "phone": "3005234321", 99 | "default": True, 100 | "city": "Bogota", 101 | "address": "Cr 4 # 55 36", 102 | "phone": "3005234321", 103 | "cell_phone": "3010000001" 104 | } 105 | 106 | customer=objepayco.customer.create(customer_info) 107 | 108 | Retrieve 109 | ****** 110 | .. code-block:: python 111 | 112 | customer=objepayco.customer.get("id_client") 113 | 114 | List 115 | ****** 116 | .. code-block:: python 117 | 118 | customer_info = { 119 | "page": 1, #number of pages 120 | "perPage": 5 #number of customers per page 121 | } 122 | customers = objepayco.customer.getlist(customer_info) 123 | 124 | Update 125 | ****** 126 | .. code-block:: python 127 | 128 | update_customer_info = { 129 | "customerId": "id_client", 130 | "name": "Alex" 131 | } 132 | 133 | customer =objepayco.customer.update(update_customer_info) 134 | 135 | Delete Token 136 | ****** 137 | .. code-block:: python 138 | 139 | delete_customer_info = { 140 | "franchise": "visa", 141 | "mask": "457562******0326", 142 | "customer_id":"id_client" 143 | } 144 | 145 | customer =objepayco.customer.delete(delete_customer_info) 146 | 147 | 148 | 149 | Add new token default to card existed 150 | ****** 151 | .. code-block:: python 152 | 153 | customer_info = { 154 | "customer_id":"id_client", 155 | "token": "**********Q2ZLD9", 156 | "franchise":"visa", 157 | "mask":"457562******0326" 158 | } 159 | customer=objepayco.customer.addDefaultCard(customer_info) 160 | 161 | 162 | Add new token to customer existed 163 | ****** 164 | .. code-block:: python 165 | 166 | customer_info = { 167 | "token_card": "6tWRMjsiDGPds2Krb", 168 | "customer_id":"id_client" 169 | } 170 | customer=objepayco.customer.addNewToken(customer_info) 171 | 172 | 173 | 174 | 175 | Plans 176 | #### 177 | 178 | Create 179 | ****** 180 | 181 | .. code-block:: python 182 | 183 | plan_info = { 184 | "id_plan": "coursereact", 185 | "name": "Course react js", 186 | "description": "Course react and redux", 187 | "amount": 35700, 188 | "currency": "cop", 189 | "interval": "month", 190 | "interval_count": 1, 191 | "trial_days": 30, 192 | "ip": "000.00.000.000", 193 | "iva": 5700, 194 | "ico": 0, 195 | "planLink":"https://github.com/epayco", 196 | "greetMessage":"discounted react and redux course", 197 | "linkExpirationDate":"2025-03-11", 198 | "subscriptionLimit": 10, #Subscription limit between 0 and 10000 199 | "imgUrl":"https://epayco.com/wp-content/uploads/2023/04/logo-blanco.svg", 200 | "discountValue":5000, #discount value 201 | "discountPercentage":19, #discount percentage 202 | "transactionalLimit": 2, #transactional Limit 203 | "additionalChargePercentage":0.0, #Additional charge percentage limit 204 | "firstPaymentAdditionalCost":45700 #Installation Cost 205 | } 206 | 207 | plan = objepayco.plan.create(plan_info) 208 | 209 | 210 | Retrieve 211 | ****** 212 | .. code-block:: python 213 | 214 | plan = objepayco.plan.get("coursereact") 215 | 216 | List 217 | ****** 218 | .. code-block:: python 219 | 220 | planes = objepayco.plan.getlist() 221 | 222 | Remove 223 | ****** 224 | .. code-block:: python 225 | 226 | plan = objepayco.plan.delete("coursereact") 227 | 228 | Upadate 229 | ****** 230 | .. code-block:: python 231 | 232 | plan_info_update = { 233 | "name": "Course react js", 234 | "description": "Course react and redux", 235 | "amount": 35700, 236 | "currency": "cop", 237 | "interval": "month", 238 | "interval_count": 1, 239 | "trial_days": 30, 240 | "ip": "170.00.000.000", 241 | "iva": 1900, 242 | "ico": 0, 243 | #"transactionalLimit": 3, 244 | #"additionalChargePercentage":0.0, 245 | #"afterPayment":"message after paying" 246 | } 247 | plan = objepayco.plan.update(id_plan, plan_info_update) 248 | 249 | Subscriptions 250 | #### 251 | 252 | Create 253 | ****** 254 | .. code-block:: python 255 | 256 | subscription_info = { 257 | "id_plan": "coursereact2", 258 | "customer": "9xRxhaJ2YmLTkT5uz", 259 | "token_card": "eXj5Wdqgj7xzvC7AR", 260 | "doc_type": "CC", 261 | "doc_number": "0000000000", 262 | #Optional parameter: if these parameter it's not send, system get ePayco dashboard's url_confirmation 263 | "url_confirmation": "https://tudominio.com/confirmacion.php", 264 | "method_confirmation": "POST" 265 | } 266 | 267 | sub=objepayco.subscriptions.create(subscription_info) 268 | 269 | Retrieve 270 | ****** 271 | .. code-block:: python 272 | 273 | sub=objepayco.subscriptions.get("efPXtZ5r4nZRoPtjZ") 274 | 275 | List 276 | ****** 277 | .. code-block:: python 278 | 279 | sub=objepayco.subscriptions.getlist() 280 | 281 | Cancel 282 | ****** 283 | .. code-block:: python 284 | 285 | sub=objepayco.subscriptions.cancel("fayE66HxYbxWydaN8") 286 | 287 | Pay Subscription 288 | ****** 289 | .. code-block:: python 290 | 291 | subscription_info = { 292 | "id_plan": "coursereact", 293 | "customer": "A6ZGiJ6rgxK5RB2WT", 294 | "token_card": "eXj5Wdqgj7xzvC7AR", 295 | "doc_type": "CC", 296 | "doc_number": "1000000", 297 | "ip":"190.000.000.000" #This is the client's IP, it is required 298 | 299 | } 300 | 301 | sub = objepayco.subscriptions.charge(subscription_info) 302 | 303 | PSE 304 | #### 305 | 306 | List Banks 307 | ***** 308 | .. code-block:: python 309 | 310 | banks = objepayco.bank.pseBank() 311 | 312 | Create 313 | ***** 314 | .. code-block:: python 315 | 316 | pse_info = { 317 | "bank": "1007", 318 | "invoice": "147205", 319 | "description": "pay test", 320 | "value": "116000", 321 | "tax": float("16000"), 322 | "tax_base": float("100000"), 323 | "currency": "COP", 324 | "type_person": "0", 325 | "doc_type": "CC", 326 | "docNumber": "10000000", 327 | "name": "testing", 328 | "last_name": "PAYCO", 329 | "email": "no-responder@payco.co", 330 | "country": "CO", 331 | "cellPhone": "3010000001", 332 | "ip": "190.000.000.000", # This is the client's IP, it is required, 333 | "url_response": "https://tudominio.com/respuesta.php", 334 | "url_confirmation": "https://tudominio.com/confirmacion.php", 335 | "metodoconfirmacion": "GET", 336 | # Los parámetros extras deben ser enviados tipo string, si se envía tipo array generara error. 337 | "extra1": "", 338 | "extra2": "", 339 | "extra3": "", 340 | "extra4": "", 341 | "extra5": "", 342 | "extra6": "", 343 | "extra7": "" 344 | } 345 | 346 | pse = objepayco.bank.create(pse_info) 347 | 348 | Retrieve 349 | ***** 350 | .. code-block:: python 351 | 352 | pse = objepayco.bank.pseTransaction("ticketId") 353 | 354 | Split Payments 355 | ***** 356 | 357 | Previous requirements: https://docs.epayco.co/tools/split-payment 358 | ***** 359 | 360 | 361 | Split payment 362 | ***** 363 | 364 | .. code-block:: python 365 | 366 | import json 367 | 368 | pse_info = { 369 | #Other customary parameters... 370 | "splitpayment":"true", 371 | "split_app_id":"P_CUST_ID_CLIENTE APPLICATION", 372 | "split_merchant_id":"P_CUST_ID_CLIENTE COMMERCE", 373 | "split_type" : "01", 374 | "split_primary_receiver" : "P_CUST_ID_CLIENTE APPLICATION", 375 | "split_primary_receiver_fee":"80000" 376 | "split_receivers": json.dumps([ 377 | {"id":"P_CUST_ID_CLIENTE 1 RECEIVER","total":"58000","iva":"8000","base_iva":"50000","fee":"10"}, 378 | {"id":"P_CUST_ID_CLIENTE 2 RECEIVER","total":"58000","iva":"8000","base_iva":"50000", "fee":"10"} 379 | ]) 380 | } 381 | 382 | pse_split = objepayco.bank.create(pse_info) 383 | 384 | 385 | Cash 386 | #### 387 | 388 | Create 389 | ***** 390 | .. code-block:: python 391 | 392 | # paymentMethod: EF=> efecty, GA=>gana, PR=>puntored, RS=>redservi, SR=>sured 393 | cash_info = { 394 | "paymentMethod" :"EF", 395 | "invoice": "1472050778", 396 | "description": "pay test", 397 | "value": "116000", 398 | "tax": "16000", 399 | "tax_base": "100000", 400 | "currency": "COP", 401 | "type_person": "0", 402 | "doc_type": "CC", 403 | "docNumber": "100000", 404 | "name": "testing", 405 | "last_name": "PAYCO", 406 | "email": "test@mailinator.com", 407 | "cellPhone": "3010000001", 408 | "end_date": "2025-02-05", 409 | "ip": "190.000.000.000", # This is the client's IP, it is required, 410 | "url_response": "https://tudominio.com/respuesta.php", 411 | "url_confirmation": "https://tudominio.com/confirmacion.php", 412 | "metodoconfirmacion": "GET", 413 | # Los parámetros extras deben ser enviados tipo string, si se envía tipo array generara error. 414 | "extra1": "", 415 | "extra2": "", 416 | "extra3": "", 417 | "extra4": "", 418 | "extra5": "", 419 | "extra6": "", 420 | "extra7": "" 421 | } 422 | 423 | cash = objepayco.cash.create(cash_info) 424 | 425 | Retrieve 426 | ***** 427 | .. code-block:: python 428 | 429 | cash = epayco.cash.get("ref_payco") 430 | 431 | 432 | 433 | Split Payments 434 | ***** 435 | 436 | Previous requirements: https://docs.epayco.co/tools/split-payment 437 | 438 | 439 | 440 | Split payment: 441 | **** 442 | 443 | use the following attributes in case you need to do a dispersion with one or multiple providers 444 | 445 | .. code-block:: python 446 | 447 | import json 448 | 449 | payment_info = { 450 | #Other customary parameters... 451 | "splitpayment":"true", 452 | "split_app_id":"P_CUST_ID_CLIENTE APPLICATION", 453 | "split_merchant_id":"P_CUST_ID_CLIENTE COMMERCE", 454 | "split_type" : "02", 455 | "split_primary_receiver" : "P_CUST_ID_CLIENTE APPLICATION", 456 | "split_primary_receiver_fee":"0", 457 | "split_rule":'multiple', #si se envía este parámetro el campo split_receivers se vuelve obligatorio 458 | "split_receivers":json.dumps([ 459 | {"id":"P_CUST_ID_CLIENTE 1 RECEIVER","total":"58000","iva":"8000","base_iva":"50000","fee":"10"}, 460 | {"id":"P_CUST_ID_CLIENTE 2 RECEIVER","total":"58000","iva":"8000","base_iva":"50000", "fee":"10"} 461 | ]) #campo obligatorio sí se envía split_rule 462 | } 463 | 464 | cash_info_split = objepayco.cash.create('efecty',cash_info) 465 | 466 | 467 | 468 | 469 | 470 | Payment 471 | #### 472 | 473 | Create 474 | ***** 475 | .. code-block:: python 476 | 477 | payment_info = { 478 | "token_card": "token_card", 479 | "customer_id": "customer_id", 480 | "doc_type": "CC", 481 | "doc_number": "1000000", 482 | "name": "John", 483 | "last_name": "Doe", 484 | "email": "example@email.com", 485 | "bill": "OR-1234", 486 | "description": "Test Payment", 487 | "country": "CO", 488 | "city": "bogota", 489 | "value": "116000", 490 | "tax": "16000", 491 | "tax_base": "100000", 492 | "currency": "COP", 493 | "dues": "12", 494 | "ip":"190.000.000.000", #This is the client's IP, it is required 495 | "url_response": "https://tudominio.com/respuesta.php", 496 | "url_confirmation": "https://tudominio.com/confirmacion.php", 497 | "method_confirmation": "GET", 498 | "use_default_card_customer":True, # if the user wants to be charged with the card that the customer currently has as default = true 499 | #Los parámetros extras deben ser enviados tipo string, si se envía tipo array generara error. 500 | "extra1": "", 501 | "extra2": "", 502 | "extra3": "", 503 | "extra4": "", 504 | "extra5": "", 505 | "extra6": "", 506 | "extra7": "" 507 | } 508 | 509 | pay = objepayco.charge.create(payment_info) 510 | 511 | Retrieve 512 | ***** 513 | 514 | .. code-block:: python 515 | 516 | pay = epayco.charge.get("ref_payco") 517 | 518 | 519 | Split Payments 520 | ***** 521 | 522 | Previous requirements https://docs.epayco.co/tools/split-payment 523 | 524 | 525 | Split payment 526 | **** 527 | 528 | use the following attributes in case you need to do a dispersion with one or multiple providers 529 | 530 | .. code-block:: python 531 | 532 | import json 533 | 534 | payment_info = { 535 | #Other customary parameters... 536 | "splitpayment":"true", 537 | "split_app_id":"P_CUST_ID_CLIENTE APPLICATION", 538 | "split_merchant_id":"P_CUST_ID_CLIENTE COMMERCE", 539 | "split_type" : "02", 540 | "split_primary_receiver" : "P_CUST_ID_CLIENTE APPLICATION", 541 | "split_primary_receiver_fee":"0", 542 | "split_rule":'multiple', #si se envía este parámetro el campo split_receivers se vuelve obligatorio 543 | "split_receivers":[ 544 | {"id":"P_CUST_ID_CLIENTE 1 RECEIVER","total":"58000","iva":"8000","base_iva":"50000","fee":"10"}, 545 | {"id":"P_CUST_ID_CLIENTE 2 RECEIVER","total":"58000","iva":"8000","base_iva":"50000", "fee":"10"} 546 | ] #campo obligatorio sí se envía split_rule 547 | } 548 | 549 | pay_split = objepayco.charge.create(payment_info) 550 | 551 | 552 | Daviplata 553 | #### 554 | 555 | Create 556 | ***** 557 | 558 | .. code-block:: python 559 | 560 | payment_info = { 561 | "doc_type": "CC", 562 | "document": "1053814580414720", 563 | "name": "Testing", 564 | "last_name": "PAYCO", 565 | "email": "exmaple@epayco.co", 566 | "ind_country": "57", 567 | "phone": "314853222200033", 568 | "country": "CO", 569 | "city": "bogota", 570 | "address": "Calle de prueba", 571 | "ip": "189.176.0.1", 572 | "currency": "COP", 573 | "description": "ejemplo de transaccion con daviplata", 574 | "value": "100", 575 | "tax": "0", 576 | "ico": "0" 577 | "tax_base": "0", 578 | "method_confirmation": "GET", 579 | "url_response": "https://tudominio.com/respuesta.php", 580 | "url_confirmation": "https://tudominio.com/confirmacion.php", 581 | "extra1": "", 582 | "extra2": "", 583 | "extra3": "", 584 | "extra4": "", 585 | "extra5": "", 586 | "extra6": "", 587 | "extra7": "", 588 | "extra8": "", 589 | "extra9": "", 590 | "extra10": "" 591 | } 592 | 593 | daviplata = objepayco.daviplata.create(payment_info) 594 | 595 | confirm transaccion 596 | ***** 597 | 598 | .. code-block:: python 599 | 600 | confirm = { 601 | "ref_payco": "45508846", # It is obtained from the create response 602 | "id_session_token": "45081749", # It is obtained from the create response 603 | "otp": "2580" 604 | } 605 | 606 | daviplata = objepayco.daviplata.confirm(payment_info) 607 | 608 | Safetypay 609 | #### 610 | 611 | Create 612 | ***** 613 | 614 | .. code-block:: python 615 | 616 | payment_info = { 617 | "cash": "1", 618 | "end_date": "2021-08-05", 619 | "doc_type": "CC", 620 | "document"": "123456789", 621 | "name": "Jhon", 622 | "last_name": "doe", 623 | "email": "jhon.doe@yopmail.com", 624 | "ind_country": "57", 625 | "phone": "3003003434", 626 | "country": "CO", 627 | "invoice": "fac-01", # opcional 628 | "city": "N/A", 629 | "address": "N/A", 630 | "ip": "192.168.100.100", 631 | "currency": "COP", 632 | "description": "Thu Jun 17 2021 11:37:01 GMT-0400 (hora de Venezuela)", 633 | "value": 100000, 634 | "tax": 0, 635 | "ico": 0, 636 | "tax_base": 0, 637 | "url_confirmation": "https://tudominio.com/respuesta.php", 638 | "url_response": "https://tudominio.com/respuesta.php", 639 | "method_confirmation": "POST", 640 | "extra1": "", 641 | "extra2": "", 642 | "extra3": "", 643 | "extra4": "", 644 | "extra5": "", 645 | "extra6": "", 646 | "extra7": "", 647 | "extra8": "", 648 | "extra9": "", 649 | "extra10": "" 650 | } 651 | 652 | safetypay = objepayco.safetypay.create(payment_info) 653 | -------------------------------------------------------------------------------- /epaycosdk/__init__.py: -------------------------------------------------------------------------------- 1 | import epaycosdk.epayco as epayco 2 | -------------------------------------------------------------------------------- /epaycosdk/client.py: -------------------------------------------------------------------------------- 1 | import urllib.request 2 | import urllib.parse 3 | import ssl 4 | import json 5 | import base64 6 | import hashlib 7 | import requests 8 | import epaycosdk.errors as errors 9 | import os 10 | import sys 11 | import traceback 12 | from requests.exceptions import ConnectionError 13 | from pathlib import Path 14 | from requests import Session 15 | import os 16 | from dotenv import load_dotenv 17 | load_dotenv() 18 | 19 | # No verificar el certifcado para los request 20 | ssl._create_default_https_context = ssl._create_unverified_context 21 | 22 | BS = 16 23 | pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 24 | unpad = lambda s : s[0:-(s[-1])] 25 | 26 | BASE_DIR = Path(__file__).resolve().parent.parent 27 | EPAYCO_KEY_LANG_FILE = str(BASE_DIR.joinpath('epaycosdk/utils/key_lang.json')) 28 | EPAYCO_KEY_LANG_FILE_APIFY = str(BASE_DIR.joinpath('epaycosdk/utils/key_lang_apify.json')) 29 | 30 | 31 | class Util(): 32 | 33 | def setKeys(self, array={},sp=''): 34 | file = open(EPAYCO_KEY_LANG_FILE, 'r').read() 35 | values = json.loads(file) 36 | aux = {} 37 | for key, value in array.items(): 38 | if key in values: 39 | aux[values[key]] = value 40 | else: 41 | aux[key] = value 42 | return aux 43 | 44 | def setKeys_apify(self, array={}): 45 | file = open(EPAYCO_KEY_LANG_FILE_APIFY, 'r').read() 46 | values = json.loads(file) 47 | aux = {} 48 | for key, value in array.items(): 49 | if key in values: 50 | aux[values[key]] = value 51 | else: 52 | aux[key] = value 53 | return aux 54 | 55 | 56 | class Auth: 57 | def __init__( self, api_key, private_key ): 58 | self.api_key = api_key 59 | self.private_key = private_key 60 | 61 | def make(self, BASE_URL, BASE_URL_APIFY, apify): 62 | url = BASE_URL_APIFY + "/login" if apify else BASE_URL + "/v1/auth/login" 63 | payload = "{\"public_key\":\""+self.api_key+"\",\"private_key\":\""+self.private_key+"\"}" 64 | headers = { 65 | 'Content-Type': 'application/json', 66 | 'type': 'sdk-jwt', 67 | 'Accept': 'application/json' 68 | } 69 | 70 | if (apify): 71 | text = "{public}:{private}".format( 72 | public=self.api_key, 73 | private=self.private_key 74 | ) 75 | encode = base64.b64encode(text.encode("utf-8")) 76 | token = str(encode, "utf-8") 77 | headers["Authorization"] = "Basic {token}".format(token=token) 78 | payload = "" 79 | response = requests.request("POST", url, headers=headers, data = payload) 80 | data=response.text.encode('utf8') 81 | json_data=json.loads(data) 82 | bearer_token=json_data['token'] if apify else json_data['bearer_token'] 83 | return bearer_token 84 | 85 | class NoRebuildAuthSession(Session): 86 | def rebuild_auth(self, prepared_request, response): 87 | """ 88 | No code here means requests will always preserve the Authorization 89 | header when redirected. 90 | Be careful not to leak your credentials to untrusted hosts! 91 | """ 92 | 93 | class Client: 94 | 95 | BASE_URL = os.getenv("BASE_URL_SDK") if os.getenv("BASE_URL_SDK") else "https://api.secure.payco.co" 96 | BASE_URL_SECURE = os.getenv("SECURE_URL_SDK") if os.getenv("SECURE_URL_SDK") else"ttps://secure.payco.co" 97 | ENTORNO = os.getenv("ENTORNO_SDK") if os.getenv("ENTORNO_SDK") else "/restpagos" 98 | BASE_URL_APIFY = os.getenv("BASE_URL_APIFY") if os.getenv("BASE_URL_APIFY") else "https://apify.epayco.co" 99 | IV = "0000000000000000" 100 | LANGUAGE = "python" 101 | SWITCH= False 102 | 103 | def __init__(self): 104 | pass 105 | 106 | """ 107 | Make request and return a Python object from the JSON response. If 108 | HTTP method is DELETE return True for 204 response, false otherwise. 109 | :param method: String with the HTTP method 110 | :param url: String with the EndPoint Api 111 | :param api_key: String with the API key 112 | :param data: Dictionary with query strings 113 | :param private_key: String with the Private key Api 114 | :param test: String TRUE O FALSE transaction in pruebas or production 115 | :param swich: Dictionary with data that will be sent 116 | :param lang: String languaje response errors 117 | :return: Native python object resulting of the JSON deserialization of the API response 118 | """ 119 | 120 | 121 | def request(self,method='POST',url="",api_key="",data={}, private_key="",test="", switch="", lang="",cashdata="",dt="", apify=False ): 122 | auth = Auth(api_key, private_key) 123 | authentication = auth.make(self.BASE_URL,self.BASE_URL_APIFY,apify) 124 | token_bearer = 'Bearer ' +authentication 125 | util = Util() 126 | if(hasattr(data, "__len__")): 127 | if(apify): 128 | data = util.setKeys_apify(data) 129 | elif(switch): 130 | data = util.setKeys(data) 131 | 132 | self.SWITCH=switch 133 | self.APIFY=apify 134 | headers = { 135 | 'Content-Type': 'application/json', 136 | 'type': 'sdk-jwt', 137 | 'lang': 'PYTHON', 138 | 'Authorization': token_bearer 139 | } 140 | 141 | try: 142 | if (method == "GET"): 143 | if(apify): 144 | response=requests.get(self.build_url(url), data={},headers=headers) 145 | elif (switch): 146 | if test == True or test == "true": 147 | test = "TRUE" 148 | else: 149 | test = "FALSE" 150 | addData = { 151 | 'public_key': api_key, 152 | #'i': base64.b64encode(self.IV.encode('ascii')), 153 | 'lenguaje': self.LANGUAGE, 154 | 'enpruebas': test, 155 | } 156 | url_params = addData 157 | url_params.update(data) 158 | response=requests.get(self.build_url(url), data={},params=url_params,auth=(api_key, ""),headers=headers) 159 | 160 | else: 161 | url_params=data 162 | payload = {} 163 | # session = NoRebuildAuthSession() 164 | response = requests.get(self.build_url(url), headers=headers, data = payload, params=url_params) 165 | elif (method == "POST"): 166 | for key, value in data.items(): 167 | if isinstance(value, bytes): 168 | data[key] = value.decode('utf-8') 169 | data["extras_epayco"] = json.dumps({"extra5":"P43"}) 170 | if (switch): 171 | if test == True or test == "true": 172 | test= "TRUE" 173 | else: 174 | test= "FALSE" 175 | addData = { 176 | 'public_key': api_key, 177 | #'i': base64.b64encode(self.IV.encode('ascii')), 178 | 'enpruebas': test, 179 | 'lenguaje': self.LANGUAGE, 180 | 'p': '' 181 | } 182 | enddata = {} 183 | enddata.update(data) 184 | enddata.update(addData) 185 | data=enddata 186 | payload = json.dumps(data) 187 | #response = requests.post(self.build_url(url),params=data, auth=(api_key, ''),headers=headers) 188 | response = requests.request("POST", self.build_url(url), headers=headers, data=payload) 189 | else: 190 | #Agregamos la llave publica 191 | if(dt): 192 | data=json.dumps(data) 193 | response = requests.request("POST", self.build_url(url),headers=headers, json=data) 194 | else: 195 | enddata = {} 196 | data.update({'test': test}) 197 | enddata.update(data) 198 | data = enddata 199 | payload = json.dumps(data) 200 | # response = requests.post(self.build_url(url), params=data, headers=headers) 201 | response = requests.request("POST", self.build_url(url), headers=headers, data=payload) 202 | elif (method == "PATCH"): 203 | response = requests.request( 204 | method, 205 | self.build_url(url), 206 | data=json.dumps(data), 207 | auth=(token_bearer, ""), 208 | headers=headers 209 | ) 210 | elif (method == "DELETE"): 211 | response = requests.request( 212 | method, 213 | self.build_url(url), 214 | data=json.dumps(data), 215 | auth=(token_bearer, ""), 216 | headers=headers 217 | ) 218 | except Exception as e: 219 | print(f"Se ha producido un error: {e}") 220 | #traceback.print_exc() 221 | raise errors.ErrorException(lang, 101) 222 | 223 | if (response.status_code >= 200 and response.status_code <= 206): 224 | if (method == "DELETE"): 225 | return response.status_code == 204 or response.status_code == 200 226 | 227 | return response.json() 228 | 229 | if (response.status_code == 400): 230 | try: 231 | return response.json() 232 | raise errors.ErrorException(lang, 103) 233 | except errors.ErrorException as e: 234 | print(e) 235 | 236 | if (response.status_code == 401): 237 | try: 238 | raise errors.ErrorException(lang, 104) 239 | except errors.ErrorException as e: 240 | print(e) 241 | 242 | if (response.status_code == 404): 243 | try: 244 | raise errors.ErrorException(lang, 105) 245 | except errors.ErrorException as e: 246 | print(e) 247 | 248 | if (response.status_code == 403): 249 | try: 250 | raise errors.ErrorException(lang, 106) 251 | except errors.ErrorException as e: 252 | print(e) 253 | 254 | if (response.status_code == 405): 255 | try: 256 | raise errors.ErrorException(lang, 107) 257 | except errors.ErrorException as e: 258 | print(e) 259 | 260 | try: 261 | raise errors.ErrorException(lang, 102) 262 | except errors.ErrorException as e: 263 | print(e) 264 | 265 | def build_url(self,endpoint): 266 | """ 267 | Build complete URL from API endpoint 268 | :param endpoint: String with the endpoint, ex: /v1/charges/ 269 | :return: String with complete URL, ex: https://api.secure.payco.co/v1/charges/ 270 | """ 271 | if(self.APIFY): 272 | return "{base_url}/{endpoint}".format( 273 | base_url=self.BASE_URL_APIFY, 274 | endpoint=endpoint 275 | ) 276 | elif(self.SWITCH): 277 | return "{base_url}{entorno}{endpoint}".format( 278 | base_url=self.BASE_URL_SECURE, 279 | entorno=self.ENTORNO, 280 | endpoint=endpoint 281 | ) 282 | else: 283 | return "{base_url}/{endpoint}".format( 284 | base_url=self.BASE_URL, 285 | endpoint=endpoint 286 | ) 287 | -------------------------------------------------------------------------------- /epaycosdk/epayco.py: -------------------------------------------------------------------------------- 1 | import epaycosdk.resources 2 | from epaycosdk.resources import Token 3 | from epaycosdk.resources import Customers 4 | from epaycosdk.resources import Plan 5 | from epaycosdk.resources import Subscriptions 6 | from epaycosdk.resources import Bank 7 | from epaycosdk.resources import Cash 8 | from epaycosdk.resources import Charge 9 | from epaycosdk.resources import Safetypay 10 | from epaycosdk.resources import Daviplata 11 | 12 | class Epayco: 13 | 14 | public_key = "" 15 | api_key = "" 16 | test = False 17 | lang = "ES" 18 | 19 | def __init__(self, options): 20 | self.api_key = options["apiKey"] 21 | self.private_key = options["privateKey"] 22 | self.test = "true" if options["test"] else "false" 23 | self.lang = options["lenguage"] 24 | 25 | self.token = Token(self) 26 | self.customer = Customers(self) 27 | self.plan = Plan(self) 28 | self.subscriptions = Subscriptions(self) 29 | self.bank = Bank(self) 30 | self.cash = Cash(self) 31 | self.charge = Charge(self) 32 | self.safetypay = Safetypay(self) 33 | self.daviplata = Daviplata(self) 34 | -------------------------------------------------------------------------------- /epaycosdk/errors.py: -------------------------------------------------------------------------------- 1 | import urllib.request 2 | import ssl 3 | import json 4 | # No verificar el certifcado para los request 5 | ssl._create_default_https_context = ssl._create_unverified_context 6 | # Se Extiende de la clase Exception y se inicializa la url en s3 7 | class EpaycoException(Exception): 8 | ERRORS_URL = "https://multimedia.epayco.co/message-api/errors.json" 9 | pass 10 | 11 | class ErrorException(EpaycoException): 12 | # Se inicializa pasando los argmentos codigo e idioma 13 | def __init__(self, idioma,code): 14 | self.code=code 15 | self.message = idioma 16 | # Se carga el json de la url se parsea y de devuelve el código del error de acuerdo al idioma 17 | def __str__(self): 18 | try: 19 | # Se carga el json de la url 20 | request = urllib.request.Request(self.ERRORS_URL) 21 | # Se abre el json de la url 22 | response = urllib.request.urlopen(request) 23 | # Se decodifica en utf8 24 | encoding = response.info().get_content_charset('utf8') 25 | errors = json.loads(response.read().decode(encoding)) 26 | # Se retorna el error de acuerdo al idioma y código pasado 27 | 28 | return f"ErrorException: {errors[str(self.code)][self.message]}" 29 | except Exception as e: 30 | return f"Error al obtener el mensaje: {str(e)}" 31 | -------------------------------------------------------------------------------- /epaycosdk/resources.py: -------------------------------------------------------------------------------- 1 | from epaycosdk.client import Client 2 | import epaycosdk.errors as errors 3 | 4 | class Resource(Client): 5 | """ 6 | * Instance epayco class 7 | * @param array $epayco 8 | */ 9 | """ 10 | 11 | def __init__(self, epayco): 12 | self.epayco = epayco 13 | 14 | 15 | """ 16 | * Constructor resource requests 17 | """ 18 | 19 | 20 | class Token(Resource): 21 | """ 22 | * Instance epayco class 23 | * @param array $epayco 24 | */ 25 | """ 26 | 27 | def create(self, options): 28 | 29 | return self.request( 30 | "POST", 31 | "v1/tokens", 32 | self.epayco.api_key, 33 | options, 34 | self.epayco.private_key, 35 | self.epayco.test, 36 | False, 37 | self.epayco.lang, 38 | False 39 | ) 40 | 41 | 42 | """ 43 | * Customer methods 44 | """ 45 | 46 | 47 | class Customers(Resource): 48 | """ 49 | * Create client and asocciate credit card 50 | * @param array $options client and token id info 51 | * @return object 52 | """ 53 | 54 | def create(self, options=None): 55 | return self.request( 56 | "POST", 57 | "payment/v1/customer/create", 58 | self.epayco.api_key, 59 | options, 60 | self.epayco.private_key, 61 | self.epayco.test, 62 | False, 63 | self.epayco.lang, 64 | False 65 | ) 66 | 67 | """ 68 | * Get client for id 69 | * @param String $uid id client 70 | * @return object 71 | """ 72 | 73 | def get(self, uid): 74 | return self.request( 75 | "GET", 76 | "payment/v1/customer/" + self.epayco.api_key + "/" + uid, 77 | self.epayco.api_key, 78 | None, 79 | self.epayco.private_key, 80 | self.epayco.test, 81 | False, 82 | self.epayco.lang, 83 | False 84 | ) 85 | 86 | """ 87 | * Get list customer rom client epayco 88 | * @return object 89 | """ 90 | 91 | def getlist(self, options=None): 92 | return self.request( 93 | "GET", 94 | "payment/v1/customers", 95 | self.epayco.api_key, 96 | options, 97 | self.epayco.private_key, 98 | self.epayco.test, 99 | False, 100 | self.epayco.lang, 101 | False 102 | ) 103 | 104 | def update(self,uid,options): 105 | 106 | return self.request( 107 | "POST", 108 | "subscriptions/customer/update", 109 | self.epayco.api_key, 110 | options, 111 | self.epayco.private_key, 112 | self.epayco.test, 113 | False, 114 | self.epayco.lang, 115 | False, 116 | False, 117 | True 118 | ) 119 | 120 | def delete(self,options): 121 | 122 | return self.request( 123 | "POST", 124 | "v1/remove/token", 125 | self.epayco.api_key, 126 | options, 127 | self.epayco.private_key, 128 | self.epayco.test, 129 | False, 130 | self.epayco.lang, 131 | False 132 | ) 133 | 134 | def addDefaultCard(self,options): 135 | return self.request( 136 | "POST", 137 | "payment/v1/customer/reasign/card/default", 138 | self.epayco.api_key, 139 | options, 140 | self.epayco.private_key, 141 | self.epayco.test, 142 | False, 143 | self.epayco.lang, 144 | False, 145 | False, 146 | False 147 | ) 148 | 149 | def addNewToken(self,options): 150 | return self.request( 151 | "POST", 152 | "v1/customer/add/token", 153 | self.epayco.api_key, 154 | options, 155 | self.epayco.private_key, 156 | self.epayco.test, 157 | False, 158 | self.epayco.lang, 159 | False, 160 | False, 161 | False 162 | ) 163 | 164 | 165 | """ 166 | * Class Charge 167 | """ 168 | 169 | class Charge(Resource): 170 | """ 171 | * Create charge token card and customer 172 | * @param object $options data from charge 173 | * @return object 174 | """ 175 | 176 | def create(self, options=None): 177 | return self.request( 178 | "POST", 179 | "payment/v1/charge/create", 180 | self.epayco.api_key, 181 | options, 182 | self.epayco.private_key, 183 | self.epayco.test, 184 | False, 185 | self.epayco.lang, 186 | False 187 | ) 188 | 189 | def get(self, uid): 190 | 191 | return self.request( 192 | "GET", 193 | "/transaction/response.json", 194 | self.epayco.api_key, 195 | {'ref_payco': uid}, 196 | self.epayco.private_key, 197 | self.epayco.test, 198 | True, 199 | self.epayco.lang, 200 | False 201 | ) 202 | """ 203 | * Plan methods 204 | """ 205 | 206 | 207 | class Plan(Resource): 208 | """ 209 | * Create plan 210 | * @param object $options data from plan 211 | * @return object 212 | """ 213 | 214 | def create(self, options=None): 215 | return self.request( 216 | "POST", 217 | "recurring/v1/plan/create", 218 | self.epayco.api_key, 219 | options, 220 | self.epayco.private_key, 221 | self.epayco.test, 222 | False, 223 | self.epayco.lang, 224 | False 225 | ) 226 | 227 | """ 228 | * Get plan for id 229 | * @param String $uid id plan 230 | * @return object 231 | """ 232 | 233 | def get(self, uid): 234 | options = None 235 | return self.request( 236 | "GET", 237 | "recurring/v1/plan/" + self.epayco.api_key + "/"+uid, 238 | self.epayco.api_key, 239 | options, 240 | self.epayco.private_key, 241 | self.epayco.test, 242 | False, 243 | self.epayco.lang, 244 | False 245 | ) 246 | 247 | """ 248 | * Get list all plan from client epayco 249 | * @return object 250 | """ 251 | 252 | def getlist(self): 253 | options = None 254 | 255 | return self.request( 256 | "GET", 257 | "recurring/v1/plans/" + self.epayco.api_key, 258 | self.epayco.api_key, 259 | options, 260 | self.epayco.private_key, 261 | self.epayco.test, 262 | False, 263 | self.epayco.lang, 264 | False 265 | ) 266 | 267 | """ 268 | * Update plan 269 | * @param String uid id plan 270 | * @param object options content update 271 | * @return object 272 | """ 273 | 274 | def update(self, uid, options=None): 275 | return self.request( 276 | "POST", 277 | "recurring/v1/plan/edit/" + uid, 278 | self.epayco.api_key, 279 | options, 280 | self.epayco.private_key, 281 | self.epayco.test, 282 | False, 283 | self.epayco.lang, 284 | False 285 | ) 286 | 287 | def delete(self,uid): 288 | options={} 289 | return self.request( 290 | "POST", 291 | "recurring/v1/plan/remove/" + self.epayco.api_key + "/" + uid, 292 | self.epayco.api_key, 293 | options, 294 | self.epayco.private_key, 295 | self.epayco.test, 296 | False, 297 | self.epayco.lang, 298 | False 299 | ) 300 | 301 | """ 302 | * Create subcription from clients 303 | """ 304 | 305 | 306 | class Subscriptions(Resource): 307 | """ 308 | * Create Subscription 309 | * @param object $options data from plan 310 | * @return object 311 | """ 312 | 313 | def create(self, options=None): 314 | return self.request( 315 | "POST", 316 | "recurring/v1/subscription/create", 317 | self.epayco.api_key, 318 | options, 319 | self.epayco.private_key, 320 | self.epayco.test, 321 | False, 322 | self.epayco.lang, 323 | False 324 | ) 325 | 326 | """ 327 | * Get plan subscription id 328 | * @param String $uid id subscription 329 | * @return object 330 | """ 331 | 332 | def get(self, uid): 333 | options = None 334 | return self.request( 335 | "GET", 336 | "recurring/v1/subscription/" + uid + "/" + self.epayco.api_key, 337 | self.epayco.api_key, 338 | options, 339 | self.epayco.private_key, 340 | self.epayco.test, 341 | False, 342 | self.epayco.lang, 343 | False 344 | ) 345 | 346 | """ 347 | * Get list all suscriptions from client epayco 348 | * @return object 349 | """ 350 | 351 | def getlist(self): 352 | options = None 353 | 354 | return self.request( 355 | "GET", 356 | "recurring/v1/subscriptions/" + self.epayco.api_key, 357 | self.epayco.api_key, 358 | options, 359 | self.epayco.private_key, 360 | self.epayco.test, 361 | False, 362 | self.epayco.lang, 363 | False 364 | ) 365 | 366 | """ 367 | * Update plan 368 | * @param String uid id plan 369 | * @param object options content update 370 | * @return object 371 | """ 372 | 373 | def cancel(self, uid=None): 374 | options = {'id': uid} 375 | 376 | return self.request( 377 | "POST", 378 | "recurring/v1/subscription/cancel", 379 | self.epayco.api_key, 380 | options, 381 | self.epayco.private_key, 382 | self.epayco.test, 383 | False, 384 | self.epayco.lang, 385 | False 386 | ) 387 | 388 | def charge(self, options=None): 389 | 390 | return self.request( 391 | "POST", 392 | "payment/v1/charge/subscription/create", 393 | self.epayco.api_key, 394 | options, 395 | self.epayco.private_key, 396 | self.epayco.test, 397 | False, 398 | self.epayco.lang, 399 | False 400 | ) 401 | 402 | """ 403 | * Pse methods 404 | """ 405 | 406 | 407 | class Bank(Resource): 408 | """ 409 | * Return list all banks 410 | * @return object 411 | """ 412 | 413 | def pseBank(self,options = None): 414 | if self.epayco.test == 'false': 415 | url = "/pse/bancos.json?public_key="+self.epayco.api_key+"&test=1" 416 | else: 417 | url = "/pse/bancos.json?public_key="+self.epayco.api_key 418 | return self.request( 419 | "GET", 420 | url, 421 | self.epayco.api_key, 422 | {'public_key':self.epayco.api_key}, 423 | self.epayco.private_key, 424 | self.epayco.test, 425 | True, 426 | self.epayco.lang, 427 | False 428 | ) 429 | 430 | """ 431 | * Create transaction in ACH 432 | * @param Object $options data transaction 433 | * @return object 434 | """ 435 | 436 | def create(self, options=None): 437 | return self.request( 438 | "POST", 439 | "payment/process/pse", 440 | self.epayco.api_key, 441 | options, 442 | self.epayco.private_key, 443 | self.epayco.test, 444 | True, 445 | self.epayco.lang, 446 | False, 447 | False, 448 | True 449 | ) 450 | 451 | """ 452 | * Return data transaction 453 | * @param String $uid cust id transaction 454 | * @return object 455 | """ 456 | 457 | def pseTransaction(self, uid): 458 | return self.request( 459 | "GET", 460 | "/pse/transactioninfomation.json", 461 | self.epayco.api_key, 462 | {'transactionID':uid}, 463 | self.epayco.private_key, 464 | self.epayco.test, 465 | True, 466 | self.epayco.lang, 467 | False 468 | ) 469 | 470 | def get(self, uid): 471 | 472 | return self.request( 473 | "GET", 474 | "/transaction/response.json", 475 | self.epayco.api_key, 476 | {'ref_payco': uid}, 477 | self.epayco.private_key, 478 | self.epayco.test, 479 | True, 480 | self.epayco.lang, 481 | False 482 | ) 483 | """ 484 | * Cash payment methods 485 | """ 486 | 487 | 488 | class Cash(Resource): 489 | """ 490 | * Return data payment cash 491 | * @param String $type method payment 492 | * @param String $options data transaction 493 | * @return object 494 | """ 495 | 496 | def create(self, options=None): 497 | return self.request( 498 | "POST", 499 | "payment/process/cash", 500 | self.epayco.api_key, 501 | options, 502 | self.epayco.private_key, 503 | self.epayco.test, 504 | True, 505 | self.epayco.lang, 506 | False, 507 | False, 508 | True 509 | ) 510 | 511 | def get(self, uid): 512 | 513 | return self.request( 514 | "GET", 515 | "/transaction/response.json", 516 | self.epayco.api_key, 517 | {'ref_payco': uid}, 518 | self.epayco.private_key, 519 | self.epayco.test, 520 | True, 521 | self.epayco.lang, 522 | False 523 | ) 524 | 525 | class Daviplata(Resource): 526 | def create(self, options = None): 527 | return self.request( 528 | "POST", 529 | "payment/process/daviplata", 530 | self.epayco.api_key, 531 | options, 532 | self.epayco.private_key, 533 | self.epayco.test, 534 | False, 535 | self.epayco.lang, 536 | False, 537 | False, 538 | True # apify 539 | ) 540 | 541 | def confirm(self, options = None): 542 | return self.request( 543 | "POST", 544 | "payment/confirm/daviplata", 545 | self.epayco.api_key, 546 | options, 547 | self.epayco.private_key, 548 | self.epayco.test, 549 | False, 550 | self.epayco.lang, 551 | False, 552 | False, 553 | True 554 | ) 555 | 556 | 557 | class Safetypay(Resource): 558 | def create(self, options = None): 559 | return self.request( 560 | "POST", 561 | "payment/process/safetypay", 562 | self.epayco.api_key, 563 | options, 564 | self.epayco.private_key, 565 | self.epayco.test, 566 | False, 567 | self.epayco.lang, 568 | False, 569 | False, 570 | True 571 | ) -------------------------------------------------------------------------------- /epaycosdk/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epayco/epayco-python/4fbd9b1d32fe532f45996e6478c64b8a28211e12/epaycosdk/test/__init__.py -------------------------------------------------------------------------------- /epaycosdk/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epayco/epayco-python/4fbd9b1d32fe532f45996e6478c64b8a28211e12/epaycosdk/utils/__init__.py -------------------------------------------------------------------------------- /epaycosdk/utils/key_lang.json: -------------------------------------------------------------------------------- 1 | { 2 | "bank": "banco", 3 | "invoice": "factura", 4 | "description": "descripcion", 5 | "value": "valor", 6 | "tax": "iva", 7 | "tax_base": "baseiva", 8 | "currency": "moneda", 9 | "type_person": "tipo_persona", 10 | "doc_type": "tipo_doc", 11 | "doc_number": "documento", 12 | "name": "nombres", 13 | "last_name": "apellidos", 14 | "email": "email", 15 | "country": "pais", 16 | "department": "depto", 17 | "city": "ciudad", 18 | "phone": "telefono", 19 | "cell_phone": "celular", 20 | "address": "direccion", 21 | "end_date": "fechaexpiracion", 22 | "ip": "ip", 23 | "url_response": "url_respuesta", 24 | "url_confirmation": "url_confirmacion", 25 | "method_confirmation": "method_confirmation", 26 | "metodoconfirmacion": "metodoconfirmacion", 27 | "splitpayment": "splitpayment", 28 | "split_app_id": "split_app_id", 29 | "split_merchant_id": "split_merchant_id", 30 | "split_type": "split_type", 31 | "split_primary_receiver": "split_primary_receiver", 32 | "split_primary_receiver_fee": "split_primary_receiver_fee", 33 | "split_rule": "split_rule", 34 | "split_receivers": "split_receivers" 35 | } -------------------------------------------------------------------------------- /epaycosdk/utils/key_lang_apify.json: -------------------------------------------------------------------------------- 1 | { 2 | "cash": "cash", 3 | "end_date": "expirationDate", 4 | "ref_payco": "refPayco", 5 | "id_session_token": "idSessionToken", 6 | "otp": "otp", 7 | "invoice": "invoice", 8 | "description": "description", 9 | "value": "value", 10 | "tax": "tax", 11 | "ico": "ico", 12 | "tax_base": "taxBase", 13 | "currency": "currency", 14 | "doc_type": "docType", 15 | "doc_number": "document", 16 | "name": "name", 17 | "last_name": "lastName", 18 | "email": "email", 19 | "ind_country": "indCountry", 20 | "country": "country", 21 | "city": "city", 22 | "phone": "phone", 23 | "address": "address", 24 | "ip": "ip", 25 | "test": "testMode", 26 | "url_response": "urlResponse", 27 | "url_confirmation": "urlConfirmation", 28 | "method_confirmation": "methodConfirmation" 29 | } -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from setuptools import setup, find_packages 4 | import platform 5 | 6 | setup( 7 | name="epaycosdk", 8 | version="3.3.2", 9 | include_package_data=True, 10 | author="ePayco Development Team", 11 | author_email="ricardo.saldarriaga@epayco.co", 12 | packages=find_packages(), 13 | url='https://epayco.co/', 14 | download_url="https://github.com/epayco/epayco-python", 15 | license="MIT", 16 | description="Python library for ePayco Payment API", 17 | long_description="Basic python library to interact with ePayco Payment API", 18 | install_requires=[ 19 | "requests >= 2.4.3", 20 | "pycryptodome >= 2.6.1", 21 | "python-dotenv >= 0.19.2" 22 | ], 23 | ) --------------------------------------------------------------------------------