pbb.py 8.66 KB
import base64
import json
from time import sleep

import requests
from opensipkd.base import get_settings
from opensipkd.base.tools.api import JsonRpcBillAllreadyPaidError, JsonRpcBillNotFoundError
from opensipkd.pasar.models import PartnerProduk, H2hArInvoiceDet
from pyramid_rpc.jsonrpc import JsonRpcError

from ..vendor import VendorClass

import logging

log = logging.getLogger(__name__)
import urllib3

urllib3.disable_warnings()

"""
PJDL
http://103.66.86.115:8989/interface-tangerang-1.0.0/pjdlJson/inq
http://103.66.86.115:8989/interface-tangerang-1.0.0/pjdlJson/pay

PBB
http://103.66.86.115:8989/interface-tangerang-1.0.0/pbbJson/inq
http://103.66.86.115:8989/interface-tangerang-1.0.0/pbbJson/pay

BPHTB
http://103.66.86.115:8989/interface-tangerang-1.0.0/bphtbJson/inq
http://103.66.86.115:8989/interface-tangerang-1.0.0/bphtbJson/pay


"""
class Vendor(VendorClass):
    def __init__(self, vendor_produk, invoice_det):
        VendorClass.__init__(self, vendor_produk, invoice_det=invoice_det)
        # id_pel, customer_id, cust_trx, row
        settings = get_settings()
        self.mid = 'tangselpay_mid' in settings and settings['tangselpay_mid'] or None
        self.key = 'tangselpay_key' in settings and settings['tangselpay_key'] or None
        self.url = 'tangselpay_url' in settings and settings['tangselpay_url'] or None
        key = ":".join([self.mid, self.key]).encode()
        self.auth = base64.b64encode(key).decode()
        self.inq_url = '{0}/pbbJson/inq'.format(self.url)
        self.pay_url = '{0}/pbbJson/pay'.format(self.url)

    def get_headers(self):
        return {'Authorization': 'Bearer {key}'.format(key=self.auth)}

    def get_url(self, url=None):
        return url and self.url + url or self.url

    def inquiry_field(self):
        return \
            {
                "oRef": "000001",
                "dateSettlement": "0925",
                "merchantType": "6014",
                "accountCurrency": "360",
                "terminalId": "02W001",
                "terminalName": "Mobile POS Tangsel",
                "terminalLoc": "Tangerang Selatan",
                "nop": "3676060001000100010",
                "tahunPajak": "2019"
            }

    def response_field(self):
        resp = self.response
        if resp["responseCode"] == "00":
            # oRef
            # dateSettlement
            # merchantType
            # accountCurrency
            # terminalId
            # terminalName
            # terminalLoc
            #  nop
            #  tahunPajak
            rincian = dict(
                alamat=resp["lokasi"],
                kelurahaan=resp["kelurahaan"],
                kecamatan=resp["kecamatan"],
                provinsi=resp["provinsi"],
                luas_bumi=resp["luasTanah"],
                luas_bng=resp["luasBangunan"],
                jatuh_tempo=resp["tanggalJatuhTempo"],
                pokok=resp["tagihan"],
                denda=resp["denda"],
                sub_total=resp["totalBayar"],
                admin=resp["biayaAdmin"],
                code=resp["responseCode"],
                message=resp["responseDesc"],
                discount=resp["discount"])

            self.amt_buy = rincian["sub_total"]
            harga_pokok = rincian["pokok"]+rincian["denda"]
            # denda = rincian["denda"]
            admin = rincian["admin"]
            product_id = self.invoice_det.produk.id
            if hasattr(self.invoice_det, "customer_id"):
                partner_id = self.invoice_det.customer_id
            else:
                partner_id = self.invoice_det.h2h_ar_invoice.customer_id

            discount = PartnerProduk.get_discount(partner_id, product_id)
            self.discount = discount
            self.amt_sell = int(harga_pokok) + admin - self.discount

            result = {"subtotal": int(harga_pokok),
                      "admin": admin,
                      "discount": self.discount,
                      "total": self.amt_sell,
                      'rincian': rincian}
            return result

        else:
            code = int(resp["responseCode"])
            message = resp["responseDesc"]
            if code == 54:
                raise JsonRpcBillAllreadyPaidError()
            elif code == 55:
                raise JsonRpcBillNotFoundError()
            else:
                raise JsonRpcError(code=code,
                        message=message)


    def inquiry(self):
        if not self.v_produk_kd or not self.id_pel:
            return self.set_response(message='Parameter tidak lengkap')

        self.request = self.inquiry_field()
        log.info("Inquiry Request: url: {} params {}".format(self.inq_url, self.request))
        self.save_log("inquiry")
        try:
            resp = requests.get(self.inq_url, params=self.request, verify=False,
                                headers=self.get_headers(), timeout=15)
        except:
            return self.set_response(message="Biller Not Response")

        if not resp:
            return self.set_response(message="Biller No Response")

        try:
            result = json.loads(resp.text)
        except:
            result = resp.text

        self.response = result
        log.info("Inquiry Response: %s" % self.response)
        if resp.status_code == 200:
            self.status = 1  # sukses
            parsd = self.response_field()
            if parsd:
                parsd.update(code=0,
                             message="SUCCESS",
                             status="SUCCESS")

        else:
            self.status = -1
            parsd = None

        return self.set_response(parsd)

    def payment(self):
        inq = self.inquiry()
        params = self.response
        try:
            resp = requests.post(self.inq_url, data=json.dumps(params), verify=False,
                                 headers=self.get_headers(), timeout=15)
        except:
            resp = None

        if resp is None:
            self.status = 0
            return self.set_pending(parsd)
            # todo: dibuat seolah menjadi belum di transaksikan
            # todo: membuat cron untuk melakukan pengecekan transaksi
        try:
            result = json.loads(resp.text)
            self.response = result
            log.info("Payment Response: %s" % self.response)
        except:
            result = resp.text
            self.response = result
            log.info("Payment Response: %s" % self.response)
            self.status = 0
            return self.set_pending(parsd)

        if resp.status_code == 200 and type(result) is dict:  # 0200
            data = "data" in result and result["data"] or {}
            if not data:
                self.status = 0
                return self.set_pending(parsd)

            self.vend_inv_no = "order_id" in data and data["order_id"] or self.vend_inv_no
            self.amt_buy = "price" in data and data["price"] or self.amt_buy
            parsd = self.get_headers

            self.serial_number = 'serial_number' in data and data["serial_numner"] \
                                     or self.serial_number
            return self.set_success(parsd)


        else:
            self.status = -1
            parsd = None
            return self.set_pending(parsd)

    def advice(self):
        if not self.v_produk_kd or not self.id_pel or not self.invoice_det:
            return dict(code=9999,
                        message='Parameter tidak lengkap')

        if self.kategori == 'e-payment':
            order_id = self.invoice_det.vend_inv_no
            url = self.get_url('/order/{order_id}'.format(order_id=order_id))
            params = None
            self.request = url
        else:
            params = dict(
                data=dict(
                    denom=self.v_produk_kd,
                    number=self.id_pel
                )
            )
            self.request = params
            url = self.get_url('/prepaid/purchase-get')

        self.save_log("advice")
        try:
            resp = requests.get(url, params=params, verify=False,
                                headers=self.get_headers(), timeout=15)
        except:
            return self.set_response()

        try:
            result = json.loads(resp.text)
        except:
            result = resp.text

        self.response = result
        if resp.ok:
            self.status = 1  # sukses
            data = "data" in result and result["data"] or None
            parsd = self.pars_data(data)

        elif resp.status_code == 400:
            self.status = -3
            parsd = dict(code=resp.status_code,
                         message=resp.text)
        else:
            self.status = -4
            parsd = dict(code=500,
                         message="Other Error")

        self.save_log('advice')
        return parsd