/var/www/hkosl.com/littleark/webadmin/models/Refund.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
<?php

class Refund extends BaseModel
{
    protected 
$table "refund";

    public function 
customer()
    {
        return 
$this->belongsTo('Customer');
    }

    public function 
order()
    {
        return 
$this->belongsTo('Order');
    }

    public function 
supplierOrder()
    {
        return 
$this->belongsTo('SupplierOrder');
    }

    public function 
orderItem()
    {
        return 
$this->belongsTo('OrderItem');
    }

    public function 
invoiceItem()
    {
        return 
$this->belongsTo('InvoiceItem');
    }

    public function 
paymentRefunds()
    {
        return 
$this->hasMany('PaymentRefund');
    }

    public function 
doRefund($refund_amount, &$msg)
    {
        
// $payment = $this->invoiceItem->invoice;
        // $payment = PaymentRecord::whereDeleted(0)->where('order_id', $row['order_id'])->first();

        // find the payment type of the invoice
        
$paymentRecords $this->invoiceItem->invoice->paymentRecords()->whereDeleted(0)->where('paystatus'1)->get();
        if (
count($paymentRecords) <= 0) {
            throw new 
RefundAmountException("Payment not found"1);
        }

        
// vdump("getForeignAmount: {$this->invoiceItem->invoice->getForeignAmount()}");
        // exit;
        // check paid invoice amount > $refund amount in order currency
        
if ($refund_amount $this->invoiceItem->invoice->getForeignAmount()) {
            throw new 
RefundAmountException("Invalid Refund Amount"1);
        }

        
// call the corresponding refund api
        
try {
            
$paymentRefund $this->doRefundExcute($paymentRecords$refund_amount);
        } catch (
RefundPaymentTypeException $e) {
            
vdump($e->getMessage());
            
// create a dummy refund record
            
$paymentRefund PaymentRefund::create([
                
'code'          => MasterSetting::get('ORDER_NUMBER_PREFIX') . "-R{$this->id}D-" date("YmdHis"),
                
'status'        => 'PAID',
                
'amount'        => $refund_amount,
                
'currency_code' => $paymentRecords->first()->currency_code,
            ]);
            
$msg $e->getMessage();
        } catch (
FailRefundException $e) {
            
vdump($e->getMessage());
            
$paymentRefund false;
            
$msg           $e->getMessage();
        }

        if (
$paymentRefund->id) {
            
// change refund amount to base currency
            
$based_refund_amount get_currency_price($refund_amountnull$paymentRefund->currency_code1);
            
// calculate discounted amount after refund (not updating OrderDiscount at this moment)
            // update InvoiceItem and Invoice (order, orderItem)
            
$this->invoiceItem->fill([
                
'refund_amount'    => $this->invoiceItem->refund_amount $based_refund_amount,
                
'discounted_price' => ($this->invoiceItem->price $this->invoiceItem->quantity) - $based_refund_amount,
            ])->
save();

            
$this->invoiceItem->invoice->calcAmount()->save();

            
// remove all orderDiscount for the orderItem
            
foreach ($this->orderItem->orderDiscounts as $orderDiscount) {
                
$orderDiscount->delete()->save();
            }

            
// negative CUstomerPoint in base currency
            
$customerPoint CustomerPoint::create([
                
'customer_id' => $this->customer_id,
                
'points'      => (-1) * $based_refund_amount,
                
'status'      => 'COMPLETED',
                
'table_name'  => get_class($this),
                
'table_refid' => $this->refid,
            ]);

            
// update the PayeasePaymentDtls (in payment currency) if is it not yet submitted, o/w: create a negative record to balance it
            
$supplierPayeasePaymentDtl $this->invoiceItem->PayeasePaymentDtls()->whereNotNull('supplier_id')->first();
            if(
$supplierPayeasePaymentDtl->payease_payment_submit_id){
                
// negative amount
            
}else{
                
$supplierPayeasePaymentDtl->fill([
                    
'amount' => $this->invoiceItem->getSupplierReceivableAmount(),
                ])->
save();
            }

            
$platformPayeasePaymentDtl $this->invoiceItem->PayeasePaymentDtls()->whereNull('supplier_id')->first();
            
$platformPayeasePaymentDtl->fill([
                
'amount' => $this->invoiceItem->discounted_price $supplierPayeasePaymentDtl->amount,
            ])->
save();

            
// vdump($this->invoiceItem->discounted_price, $supplierPayeasePaymentDtl->amount, $platformPayeasePaymentDtl->amount);
            // dq(1,1);
            // update CustomerPoint, invoice.gainpoint

            // TODO: send email customer
            // $this->sendEmailCustomer();
            
return "SUCCESS";
        } else {
            
$msg _lang("Failed to Refund");
            return 
"FAILED";
        }
    }

    protected function 
generatePaymentRecordCode()
    {
        return 
MasterSetting::get('ORDER_NUMBER_PREFIX') . "-R{$this->id}-" date('YmdHis');
    }

    protected function 
doRefundExcute($paymentRecords$refund_amount)
    {
        
$paymentRecord $paymentRecords->first();

        
$paymentRefund = new PaymentRefund([
            
'refund_id'     => $this->id,
            
'status'        => 'PAID',
            
'amount'        => $refund_amount,
            
'code'          => $this->generatePaymentRecordCode(),
            
'currency_code' => $paymentRecord->currency_code,
        ]);

        switch (
$paymentRecord->payment_type) {
            case 
'DOKU':
            case 
'DOKU_CREDITCARD':
                
// vdump($paymentRecord['code'], $refund_amount, "Refund", MasterSetting::get('PAYEASE_REFOPRT')); exit;
                
$payease     = new PayEaseDoku();
                
$result      $payease->ref_ack_submit($paymentRecord->code$refund_amount"Refund"MasterSetting::get('PAYEASE_REFOPRT'));
                
$json_result json_encode($result);
                
$result      json_decode($json_result);
                
$status      = ($result->v_status == 0) ? 'SUCCESS' 'FAILED';
                
$paymentRefund->fill([
                    
'amount'  => $result->v_refamount,
                    
'desc_en' => $result->v_desc,
                ]);
                break;

            case 
'TRUSTPAY':
                require_once 
"../trustpay/ebusclient/RefundRequest.php";
                
// TrustPay settings
                
putenv('ABCMerchantIniFile=' MasterSetting::get('ABC_MERCHANT_FOLDER') . '/TrustMerchant.ini');
                
// putenv('ABCMerchantIniFile=E:\\htdocs\\b2b2c\\protected\\TrustMerchant.ini');

                //1、生成退款请求对象
                
$tRequest                          = new RefundRequest();
                
$invoice_createdate                Carbon::createFromFormat('Y-m-d H:i:s'$paymentRecord->invoice->createdate);
                
$tRequest->request["OrderDate"]    = $invoice_createdate->format('Y/m/d'); //订单日期(必要信息)
                
$tRequest->request["OrderTime"]    = $invoice_createdate->format('H:i:s'); //订单时间(必要信息)
                
$tRequest->request["OrderNo"]      = substr($paymentRecord->invoice->code020); //原交易编号(必要信息)
                
$tRequest->request["NewOrderNo"]   = $paymentRefund->code//交易编号(必要信息)
                
$tRequest->request["CurrencyCode"] = 156//交易币种(必要信息)
                
$tRequest->request["TrxAmount"]    = $refund_amount//退货金额 (必要信息)
                // $tRequest->request["MerRefundAccountNo"]   = ($_POST['MerRefundAccountNo']); //商户退款账号
                // $tRequest->request["MerRefundAccountName"] = ($_POST['MerRefundAccountName']); //商户退款名
                // $tRequest->request["MerchantRemarks"]      = ($_POST['MerchantRemarks']); //附言

                //2、传送退款请求并取得退货结果
                
$tResponse $tRequest->postRequest();

                
//3、支付请求提交成功,返回结果信息
                
if ($tResponse->isSuccess()) {
                    
$status 'SUCCESS';
                    
$paymentRefund->fill([
                        
'amount'  => $tResponse->GetValue("TrxAmount"),
                        
'desc_en' => json_encode([
                            
'BatchNo'   => $tResponse->GetValue("BatchNo"),
                            
'VoucherNo' => $tResponse->GetValue("VoucherNo"),
                            
'HostDate'  => $tResponse->GetValue("HostDate"),
                            
'HostTime'  => $tResponse->GetValue("HostTime"),
                            
'iRspRef'   => $tResponse->GetValue("iRspRef"),
                        ]),
                    ]);
                } else {
                    
$status 'FAILED';
                    
// print ("ReturnCode   = [" . $tResponse->getReturnCode() . "]</br>");
                    // print ("ReturnMsg   = [" . $tResponse->getErrorMessage() . "]</br>");
                
}
                break;

            case 
'UNIONPAY':
            case 
'B2B':
            case 
'CREDITCARD':
            default:
                
// require platform admin to refund directly in Payment Gateway system
                
$status 'SUCCESS';
                
// throw new RefundPaymentTypeException(_lang("Payment type: {$paymentRecord->payment_type} is not supported"), 1);
                
break;
        }

        if (
$status == "SUCCESS") {
            
// create PaymentRefund
            
$paymentRefund->save();
            return 
$paymentRefund;
            
// return $status;
        
}

        throw new 
FailRefundException(_lang("Error Processing Request"), 1);

    }
}