iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
1
Software Development

PHP新手30天實戰金流系列 第 16

[Day16]平台串金流--退款 失敗 (ECpay 沒有退款的測試環境)

  • 分享至 

  • xImage
  •  
PHP新手30天實戰金流, Laravel6

前言

  • ECPay 退款,只有信用卡可以直接退,其餘收款方式皆需要賣家自行處理

  • ECPay 信用卡退款函式

    //信用卡關帳/退刷/取消/放棄的方法
        function DoAction() {
            return $arFeedback = ECPay_DoAction::CheckOut(array_merge($this->Action,
            array('MerchantID' => $this->MerchantID, 'EncryptType' => $this->EncryptType)
            ) ,
            $this->HashKey ,$this->HashIV ,$this->ServiceURL);
        }
    
    1. 若要執行關帳時,參數請帶:C (綠界系統自動關帳時間 20:00)
    2. 若要執行取消時,參數請帶:E (取消關帳)
    3. 若要執行退刷時,參數請帶:R (已關帳後)
    4. 若要執行放棄時,參數請帶:N (尚未關帳前)
  • 第三方信用卡刷退比較
    支付連 PChomePay:可全部刷退 / 部分刷退(每日次數無限制)
    綠界科技 ECPay:可全部刷退 / 部分刷退(每日次數無限制)
    藍新金流 NewebPay:可全部刷退 / 部分刷退(每日一次)

退款 button

axios.post('{{ route('order.applyRefund', $order) }}', { reason: input }).then(function () {
            swal('申請退款成功', '', 'success').then(function () {
              location.reload();
            });
          })

OrderController

  • 更新訂單狀態、呼叫 PaymentController
public function applyRefund(Order $order, ApplyRefundRequest $request)
{
    $this->authorize('own', $order);
        
    try {
            $paymentController = new PaymentController();
            $paymentController->refund($order, $request);
        } catch (\Throwable $th) {
            //throw $th;
            $out->writeln("error: ".$th);
        }
        
    if (!$order->paid_at) {
            throw new InvalidRequestException('該訂單未支付,不可退款');
        }
        if ($order->refund_status !== Order::REFUND_STATUS_PENDING) {
            throw new InvalidRequestException('該訂單已經申請過退款,請勿重複申請');
        }

        $extra = $order->extra ? : [];
        $extra['refund_reason'] = $request->input('reason');

        $order->update([
            'refund_status' => Order::REFUND_STATUS_APPLIED,
            'extra' => $extra,
        ]);
        

        return $order;
}

PaymentController - refund 函式

  • 請求 ECPay 處理退款
  1. 一樣建立 ECPay_AllInOne 實體
$obj = new ECPay_AllInOne();
  1. ECPay 關帳時間為 20 點,我們以此判斷要執行"取消"或是"刷退"動作
$ThatTime ="20:00:00";
    if (time() >= strtotime($ThatTime)) {
        $action = 'R';
    }else {
        $action = 'N';
    }
$obj->DoAction();
  1. 退款所需參數都有給
$the_action_arr =array(
    'MerchantTradeNo' => $order['payment_no'],
    'TradeNo' => $order['trade_no'],
    'Action' => $action,
    'TotalAmount' => $order['total_amount']
);

$capture = array(
    'MerchantTradeNo' => $order['payment_no'],
    'CaptureAMT' => 0,
    'UserRefundAMT' => 0,
    'PlatformID' => ''
);

$tradeNo = array(
    'DateType' => '',
    'BeginDate' => $order['trade_no'],
    'EndDate' => '',
    'MediaFormated' => ''
);
$obj->Capture = $capture; 
            $obj->TradeNo = $tradeNo; 
            $obj->Action = $the_action_arr; 
    
  1. 結果 error :
    "Merchant=2000214&MerchantTradeNo=&TradeNo=&RtnCode=10200074&RtnMsg=\u627e\u4e0d\u5230\u52a0\u5bc6\u91d1\u9470\uff0c\u8acb\u78ba\u8a8d\u662f\u5426\u6709\u7533\u8acb\u958b\u901a\u6b64\u4ed8\u6b3e\u65b9\u5f0f"
    10200074 找不到加密金鑰,請確認是否有申請開通此付款方式

不知道原因

在 ECPay sdk 的 DoAction 函式:

{
    "ServiceURL": "https://payment.ecpay.com.tw/CreditDetail/DoAction",
    "ServiceMethod": "ServiceMethod",
    "HashKey": "5294y06JbISpM5x9",
    "HashIV": "v77hoKGq4kWxNNIS",
    "MerchantID": "2000214",
    "PaymentType": "aio",
    "Send": {
        "ReturnURL": "http://aa9beef5.ngrok.io/payment/website/listenPayResult",
        "ClientBackURL": "http://aa9beef5.ngrok.io/orders",
        "OrderResultURL": "http://aa9beef5.ngrok.io/payment/website/notify",
        "MerchantTradeNo": "01029503931569996183",
        "MerchantTradeDate": "2019/10/02 14:25:49",
        "PaymentType": "aio",
        "TotalAmount": "6623",
        "TradeDesc": "ecpay test",
        "ChoosePayment": "Credit",
        "Remark": "",
        "ChooseSubPayment": "",
        "NeedExtraPaidInfo": "N",
        "DeviceSource": "",
        "IgnorePayment": "",
        "PlatformID": "",
        "InvoiceMark": "",
        "Items": [],
        "StoreID": "",
        "CustomField1": "",
        "CustomField2": "",
        "CustomField3": "",
        "CustomField4": "",
        "HoldTradeAMT": 0
    },
    "SendExtend": [],
    "Query": {
        "MerchantTradeNo": "",
        "TimeStamp": ""
    },
    "Action": {
        "MerchantTradeNo": "01029503931569996183",
        "TradeNo": "1910021403031486",
        "Action": "N",
        "TotalAmount": "6623"
    },
    "EncryptType": "1",
    "Capture": {
        "MerchantTradeNo": "",
        "CaptureAMT": 0,
        "UserRefundAMT": 0,
        "PlatformID": ""
    },
    "TradeNo": {
        "DateType": "",
        "BeginDate": "",
        "EndDate": "",
        "MediaFormated": ""
    },
    "Trade": {
        "CreditRefundId": "",
        "CreditAmount": "",
        "CreditCheckCode": ""
    },
    "Funding": {
        "PayDateType": "",
        "StartDate": "",
        "EndDate": ""
    }
}


上一篇
[Day15]平台串金流--付款(下) / 超商付款 ECPay
下一篇
[Day17]平台串金流-- apple pay 未測試
系列文
PHP新手30天實戰金流34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
eric19740521
iT邦新手 1 級 ‧ 2021-07-01 16:03:37

很棒!!!剛好要做刷退的動作
謝謝提供

退刷...手冊上說只能正式環境使用喔!!

我要留言

立即登入留言