I am getting this error when I try to use my sandbox account on my local server to get credit card payments. I have no idea how to handle this any help will be appreciated. Here is the error I received:
int(400)
string(212) "{"name":"DUPLICATE_REQUEST_ID","message":"PayPal-Request-Id header was already used.","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#DUPLICATE_REQUEST_ID","debug_id":"2845e6fe9b1b5"}"
exception 'PayPal\Exception\PayPalConnectionException' with message 'Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/payment.' in D:\xampp\htdocs\paypal1\lib\PayPal\Core\PayPalHttpConnection.php:177
Stack trace:
#0 D:\xampp\htdocs\paypal1\lib\PayPal\Transport\PayPalRestCall.php(73): PayPal\Core\PayPalHttpConnection->execute('{"intent":"sale...')
#1 D:\xampp\htdocs\paypal1\lib\PayPal\Common\PayPalResourceModel.php(102): PayPal\Transport\PayPalRestCall->execute(Array, '/v1/payments/pa...', 'POST', '{"intent":"sale...', NULL)
#2 D:\xampp\htdocs\paypal1\lib\PayPal\Api\Payment.php(579): PayPal\Common\PayPalResourceModel::executeCall('/v1/payments/pa...', 'POST', '{"intent":"sale...', NULL, Object(PayPal\Rest\ApiContext), NULL)
#3 D:\xampp\htdocs\paypal1\sample\index.php(66): PayPal\Api\Payment->create(Object(PayPal\Rest\ApiContext))
#4 {main}
Here is my index file:
<?php
require 'bootstrap.php';
use PayPal\Api\Amount;
use PayPal\Api\CreditCard;
use PayPal\Api\Details;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\Transaction;
$card = new CreditCard();
$card->setType("visa")
->setNumber("43111*******44663")
->setExpireMonth("09")
->setExpireYear("2021")
->setCvv2("012")
->setFirstName("My")
->setLastName("Name");
$fi = new FundingInstrument();
$fi->setCreditCard($card);
$payer = new Payer();
$payer->setPaymentMethod("credit_card")
->setFundingInstruments(array($fi));
$product = "rambo dfdf";
$price = 305;
$shipping = 2.00;
$total = $price + $shipping;
$item = new Item();
$item->setName($product)
->setCurrency('USD')
->setQuantity(1)
->setPrice($price);
$itemList = new ItemList();
$itemList->setItems([$item]);
$details = new Details();
$details->setShipping($shipping)
->setSubtotal($price);
$amount = new Amount();
$amount->setCurrency('USD')
->setTotal($total)
->setDetails($details);
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setInvoiceNumber(uniqid());
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setTransactions(array($transaction));
$request = clone $payment;
try {
$payment->create($apiContext);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo "<pre>";
var_dump($ex->getCode()); // Prints the Error Code
var_dump( $ex->getData()); // Prints the detailed error message
die($ex);
echo "</pre>";
} catch (Exception $ex) {
echo "<pre>";
die($ex);
echo "</pre>";
}
return $payment;
Here is my bootstrap.php file:
<?php
/*
* Sample bootstrap file.
*/
// Include the composer Autoloader
// The location of your project's vendor autoloader.
$composerAutoload = dirname(dirname(dirname(__DIR__))) . '/autoload.php';
if (!file_exists($composerAutoload)) {
//If the project is used as its own project, it would use rest-api-sdk-php composer autoloader.
$composerAutoload = dirname(__DIR__) . '/vendor/autoload.php';
if (!file_exists($composerAutoload)) {
echo "The 'vendor' folder is missing. You must run 'composer update' to resolve application dependencies.\nPlease see the README for more information.\n";
exit(1);
}
}
require $composerAutoload;
require __DIR__ . '/common.php';
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Rest\ApiContext;
// Suppress DateTime warnings, if not set already
date_default_timezone_set(#date_default_timezone_get());
// Adding Error Reporting for understanding errors properly
error_reporting(E_ALL);
ini_set('display_errors', '1');
// Replace these values by entering your own ClientId and Secret by visiting https://developer.paypal.com/webapps/developer/applications/myapps
$clientId = '*******************************';
$clientSecret = '****************************';
/**
* All default curl options are stored in the array inside the PayPalHttpConfig class. To make changes to those settings
* for your specific environments, feel free to add them using the code shown below
* Uncomment below line to override any default curl options.
*/
//PayPalHttpConfig::$defaultCurlOptions[CURLOPT_SSLVERSION] = CURL_SSLVERSION_TLSv1_2;
/** #var \Paypal\Rest\ApiContext $apiContext */
$apiContext = getApiContext($clientId, $clientSecret);
return $apiContext;
/**
* Helper method for getting an APIContext for all calls
* #param string $clientId Client ID
* #param string $clientSecret Client Secret
* #return PayPal\Rest\ApiContext
*/
function getApiContext($clientId, $clientSecret)
{
// #### SDK configuration
// Register the sdk_config.ini file in current directory
// as the configuration source.
/*
if(!defined("PP_CONFIG_PATH")) {
define("PP_CONFIG_PATH", __DIR__);
}
*/
// ### Api context
// Use an ApiContext object to authenticate
// API calls. The clientId and clientSecret for the
// OAuthTokenCredential class can be retrieved from
// developer.paypal.com
$apiContext = new ApiContext(
new OAuthTokenCredential(
$clientId,
$clientSecret
)
);
// Comment this line out and uncomment the PP_CONFIG_PATH
// 'define' block if you want to use static file
// based configuration
$apiContext->setConfig(
array(
'mode' => 'sandbox',
'log.LogEnabled' => true,
'log.FileName' => '../PayPal.log',
'log.LogLevel' => 'DEBUG', // PLEASE USE `INFO` LEVEL FOR LOGGING IN LIVE ENVIRONMENTS
'cache.enabled' => true,
// 'http.CURLOPT_CONNECTTIMEOUT' => 30
// 'http.headers.PayPal-Partner-Attribution-Id' => '123123123'
//'log.AdapterFactory' => '\PayPal\Log\DefaultLogFactory' // Factory class implementing \PayPal\Log\PayPalLogFactory
)
);
// Partner Attribution Id
// Use this header if you are a PayPal partner. Specify a unique BN Code to receive revenue attribution.
// To learn more or to request a BN Code, contact your Partner Manager or visit the PayPal Partner Portal
// $apiContext->addRequestHeader('PayPal-Partner-Attribution-Id', '123123123');
return $apiContext;
}
Try resetting the request id by replacing
$payment->create($apiContext);
With
$apiContext->resetRequestId();
$payment->create($apiContext);
Related
On my first attempt to use PayPal's REST Api, I ran into a 500 error. I googled around a bit and wasn't able to find much helpful information on PayPal 500 errors, and I have no idea what would cause it.
The error is as follows.
500
javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.[java.lang.NullPointerException]
exception 'PayPal\Exception\PayPalConnectionException' with message 'Got Http response code 500 when accessing https://api.sandbox.paypal.com/v1/payments/payment.' in /home/user/public_html/sandbox/vendor/paypal/rest-api-sdk-php/lib/PayPal/Core/PayPalHttpConnection.php:154
Stack trace:
#0 /home/user/public_html/sandbox/vendor/paypal/rest-api-sdk-php/lib/PayPal/Transport/PayPalRestCall.php(73): PayPal\Core\PayPalHttpConnection->execute('{"intent":"sale...')
#1 /home/user/public_html/sandbox/vendor/paypal/rest-api-sdk-php/lib/PayPal/Common/PayPalResourceModel.php(102): PayPal\Transport\PayPalRestCall->execute(Array, '/v1/payments/pa...', 'POST', '{"intent":"sale...', NULL)
#2 /home/user/public_html/sandbox/vendor/paypal/rest-api-sdk-php/lib/PayPal/Api/Payment.php(565): PayPal\Common\PayPalResourceModel::executeCall('/v1/payments/pa...', 'POST', '{"intent":"sale...', NULL, Object(PayPal\Rest\ApiContext), NULL)
#3 /home/user/public_html/sandbox/checkout.php(41): PayPal\Api\Payment->create(Object(PayPal\Rest\ApiContext))
#4 {main}
I also was unable to find a way to get a more verbose error message.
My code :
<?php
use PayPal\Api\Payer;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Details;
use PayPal\Api\Amount;
use PayPal\Api\Transaction;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Payment;
//include 'app.php';
require __DIR__ . '/vendor/autoload.php';
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'AfynNvA-2KwijS3pZ56jFPZwMxvObkwav8Vk4HMLc2foLahtCTPqzd_wfgt_wBtOCqqhLyk95T8LFUe0', // ClientID
'REDACTED' // ClientSecret
)
);
$price = 12;
$product = "Test";
$shipping = 0;
$total = $price + $shipping;
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item = new Item();
$item->setName($product)->setCurrency('USD')->setQuantity(1)->setPrice($price);
$itemList = new ItemList();
$itemList->setItems([$item]);
$details = new Details();
$details->setShipping($shipping)->setSubtotal($price);
$amount = new Amount();
$amount->setCurrency('USD')->setTotal($total)->setDetails($details);
$transaction = new Transaction();
$transaction->setAmount($amount)->setItemList($itemList)->setDescription("Test Payment")->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl("REDACTED")->setCancelUrl("REDACTED");
$payment = new Payment();
$payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transactions]);
try{
$payment->create($apiContext);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode(); // Prints the Error Code
echo "<br>";
echo $ex->getData(); // Prints the detailed error message
echo "<br>";
die($ex);
} catch (Exception $ex) {
die($ex);
}
echo ($payment->getApprovalLink());
?>
I'd be tempted to blame PayPal for this, as it is a 500, but it's my first use o the REST API so I assume I made a silly mistake. I've also attempted changing uniqid() to a static number, but that made no change. Should I submit a contact request to PayPal, and if so, how do I get the necessary information for that?
I've followed this tutorial to implement payment using Paypal services on my website: https://www.youtube.com/watch?v=q5Xb5r4MUB8
But when i want to flip from SandBox mode to Live mode (which is the real payment) all my transactions goes to the SandBox history (you can check it in your Paypal account).
Here is the code of the function "store()" that do the payment:
public function store(Request $request)
{
// ### CreditCard
$card = Paypalpayment::creditCard();
$card->setType("visa")
->setNumber("Some_Numbers")
->setExpireMonth("05")
->setExpireYear("2017")
->setCvv2("smth")
->setFirstName("MyName")
->setLastName("MyLastName");
$fi = Paypalpayment::fundingInstrument();
$fi->setCreditCard($card);
$payer = Paypalpayment::payer();
$payer->setPaymentMethod("credit_card")
->setFundingInstruments(array($fi));
//Payment Amount
$amount = Paypalpayment::amount();
$amount->setCurrency("EUR")
->setTotal("3");
$transaction = Paypalpayment::transaction();
$transaction->setAmount($amount)
->setDescription("Payment description")
->setInvoiceNumber(uniqid());
// ### Payment
// A Payment Resource; create one using
// the above types and intent as 'sale'
$payment = Paypalpayment::payment();
$payment->setIntent("sale")
->setPayer($payer)
->setTransactions(array($transaction));
try {
$payment->create($this->_apiContext);
} catch (\PPConnectionException $ex) {
return "Exception: " . $ex->getMessage() . PHP_EOL;
exit(1);
}
dd($payment);
}
Look what $this->_apiContext contains. There is a mode that needs to be set to live to make it work.
If not found, you can create apiContext object as shown here:
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'Live ClientId', // ClientID
'Live Client Secret' // ClientSecret
)
);
$apiContext->setConfig(
array(
'mode' => 'live',
'log.LogEnabled' => true,
'log.FileName' => 'PayPal.log',
'log.LogLevel' => 'FINE'
)
);
and use $apiContext instead when you call $payment->create();
I want to use PayPal PHP SDK API to list all my Payments/Transactions. For Sandbox Credentials I`m finally successfully, but if i switch to LIVE Credentials the Result is just:
{
"count": 0
}
...Yes im switching to LIVE with:
$apiContext->setConfig(array('mode' => 'live'));
What could be my failure? Here is my Full Code:
<?php
// 1. Autoload the SDK Package. This will include all the files and classes to your autoloader
require __DIR__ . '/autoload.php';
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'ABC', // ClientID
'DEF' // ClientSecret
)
);
$apiContext->setConfig(array('mode' => 'live'));
#$apiContext = new \PayPal\Rest\ApiContext(
# new \PayPal\Auth\OAuthTokenCredential(
# 'XYZ', // ClientID
# 'XYZZ' // ClientSecret
# )
#);
// Test
//require 'CreatePayment.php';
//use PayPal\Api\Payment;
$payment = new \PayPal\Api\Payment();
try {
$params = array('count' => 10, 'start_index' => 0);
$payments = $payment->all($params, $apiContext);
echo $payments;
} catch (Exception $ex) {
}
What is the correct way of passing in multiple products into a php paypal payment?
Currect working testcode for single product:
$api = new ApiContext(
new OAuthTokenCredential(
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
)
);
$api->setConfig([
'mode' => 'sandbox',
'log.LogEnabled' => false,
'log.FileName' => '',
'log.LogLevel' => 'FINE',
'validation.level' => 'log'
]);
$payer = new Payer();
$details = new Details();
$amount = new Amount();
$transaction = new Transaction();
$payment = new Payment();
$redirecturls = new RedirectUrls();
$payer->setPaymentMethod('paypal');
$details->setShipping('2.00')
->setTax('0.00')
->setSubtotal('20.00');
$amount->setCurrency('EUR')
->setTotal('22.00')
->setDetails($details);
$transaction->setAmount($amount)
->setDescription('Test');
$payment->setIntent('sale')
->setPayer($payer)
->setTransactions([$transaction]);
$redirecturls->setReturnUrl('RETURN URL')
->setCancelUrl('CANCEL URL');
$payment->setRedirectUrls($redirecturls);
try {
$payment->create($api);
} catch (PPConnectionException $e) {
header('Location: ERROR URL');
}
header('Location: '.$payment->getApprovalLink());
Keep in mind, this is not how I will implement it, this is just proof of concept!
I made a little CodeIgniter library with which I can easily call a payment!
If anyone is interested, don't hesitate to message me!
$this->load->library('Paypal');
$this->load->model('Config_model');
$ClientID = $this->Config_model->get('paypal.ClientID');
$Secret = $this->Config_model->get('paypal.Secret');
$defaultCurrency = $this->Config_model->get('transactions.currency');
$this->paypal->setSandbox(true);
$this->paypal->setMerchant($ClientID, $Secret);
$this->paypal->setDefaultCurrency($defaultCurrency);
$this->paypal->addItem('test', 5.3, 2);
$this->paypal->addItem('test2', 3.3, 5);
$this->paypal->setShipping(2);
$this->paypal->setTax(3);
$this->paypal->setDescription("Betalingetje");
$this->paypal->setCancelUrl('CANCEL URL HERE');
$this->paypal->setReturnUrl('RETURN URL HERE');
$this->paypal->execute();
PS: It works in conjunction with another tiny 'library' which is autoloaded. This library only includes the composer autoload.php like this:
class MyComposer
{
function __construct()
{
include("application/composer/vendor/autoload.php");
}
}
You can find the source code here: http://paypal.github.io/PayPal-PHP-SDK/sample/doc/payments/CreatePaymentUsingPayPal.html
There are so many more samples that comes packaged with the SDK itself. You can follow the instructions provided here at https://github.com/paypal/PayPal-PHP-SDK/wiki/Samples to execute samples in your local machine.
Let me know if I could be of any more help.
Here is the sample code snippet:
<?php
// # Create Payment using PayPal as payment method
// This sample code demonstrates how you can process a
// PayPal Account based Payment.
// API used: /v1/payments/payment
require __DIR__ . '/../bootstrap.php';
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
// ### Payer
// A resource representing a Payer that funds a payment
// For paypal account payments, set payment method
// to 'paypal'.
$payer = new Payer();
$payer->setPaymentMethod("paypal");
// ### Itemized information
// (Optional) Lets you specify item wise
// information
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
->setPrice(7.5);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(5)
->setPrice(2);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
// ### Additional payment details
// Use this optional field to set additional
// payment information such as tax, shipping
// charges etc.
$details = new Details();
$details->setShipping(1.2)
->setTax(1.3)
->setSubtotal(17.50);
// ### Amount
// Lets you specify a payment amount.
// You can also specify additional details
// such as shipping, tax.
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(20)
->setDetails($details);
// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it.
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setInvoiceNumber(uniqid());
// ### Redirect urls
// Set the urls that the buyer must be redirected to after
// payment approval/ cancellation.
$baseUrl = getBaseUrl();
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl("$baseUrl/ExecutePayment.php?success=true")
->setCancelUrl("$baseUrl/ExecutePayment.php?success=false");
// ### Payment
// A Payment Resource; create one using
// the above types and intent set to 'sale'
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
// For Sample Purposes Only.
$request = clone $payment;
// ### Create Payment
// Create a payment by calling the 'create' method
// passing it a valid apiContext.
// (See bootstrap.php for more on `ApiContext`)
// The return object contains the state and the
// url to which the buyer must be redirected to
// for payment approval
try {
$payment->create($apiContext);
} catch (Exception $ex) {
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
ResultPrinter::printError("Created Payment Using PayPal. Please visit the URL to Approve.", "Payment", null, $request, $ex);
exit(1);
}
// ### Get redirect url
// The API response provides the url that you must redirect
// the buyer to. Retrieve the url from the $payment->getApprovalLink()
// method
$approvalUrl = $payment->getApprovalLink();
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
ResultPrinter::printResult("Created Payment Using PayPal. Please visit the URL to Approve.", "Payment", "<a href='$approvalUrl' >$approvalUrl</a>", $request, $payment);
return $payment;
Basically what I can see is that I am failing to create the apiContext object. Can anyone see where the error is? Please tell me how I can improve the question.
Here is the error:
Fatal error: Uncaught exception 'PayPal\Exception\PPConnectionException'
with message 'Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/payment.' in /vendor/paypal
/sdk-core-php/lib/PayPal/Core/PPHttpConnection.php:104 Stack trace: #0
/vendor/paypal/sdk-core-php/lib/PayPal/Transport/PPRestCall.php(44):
PayPal\Core\PPHttpConnection->execute('{"intent":"sale...') #1 /vendor/paypal
/rest-api-sdk-php/lib/PayPal/Api/Payment.php(246): PayPal\Transport
\PPRestCall->execute(Array, '/v1/payments/pa...', 'POST',
'{"intent":"sale...') #2 /pymt.php(38): PayPal\Api
\Payment->create(Object(PayPal\Rest\ApiContext)) #3 {main} thrown in /vendor
/paypal/sdk-core-php/lib/PayPal/Core/PPHttpConnection.php on line 104
This is the PHP sample I'm using. I am trying to run it off my server. If a customer clicks the pay with paypal button, it runs the following sample script:
<?php
require __DIR__ . '/../bootstrap.php';
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
session_start();
$payer = new Payer();
$payer->setPayment_method('paypal');
$amount = new Amount();
$amount->setCurrency('USD');
$amount->setTotal('1.00');
$transaction = new Transaction();
$transaction->setAmount($amount);
$transaction->setDescription('This is the payment description.');
$baseUrl = getBaseUrl();
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturn_url('baseUrl/sale.php');
$redirectUrls->setCancel_url('baseUrl/saleFail.php');
$payment = new Payment();
$payment->setIntent('sale');
$payment->setPayer($payer);
$payment->setRedirect_urls($redirectUrls);
$payment->setTransactions(array($transaction));
try {
$payment->create($apiContext);
} catch (\PPConnectionException $ex) {
echo 'Exception: ' . $ex->getMessage() . PHP_EOL;
var_dump($ex->getData());
exit(1);
}
foreach ($payment->getLinks() as $link) {
if ($link->getRel() == 'approval_url') {
$redirectUrl = $link->getHref();
}
}
$_SESSION['paymentId'] = $payment->getId();
if(isset($redirectUrl)) {
header('Location: $redirectUrl');
exit;
}
Here's the redacted bootstrap.php:
<?php
/*
* Sample bootstrap file.
*/
// Include the composer autoloader
if(!file_exists(__DIR__ .'/vendor/autoload.php')) {
echo "The 'vendor' folder is missing. You must run 'composer update --no-dev' to resolve application dependencies.\nPlease see the README for more information.\n";
exit(1);
}
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/common.php';
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
$apiContext = getApiContext();
/**
Helper method for getting an APIContext for all calls
*
* #return PayPal\Rest\ApiContext
*/
function getApiContext() {
// ### Api context
// Use an ApiContext object to authenticate
// API calls. The clientId and clientSecret for the
// OAuthTokenCredential class can be retrieved from
// developer.paypal.com
$apiContext = new ApiContext(
new OAuthTokenCredential(
'MY CLIENT ID',
'MY SECRET'
)
);
// Register the sdk_config.ini file in current directory
// as the configuration source.
if(!defined("PP_CONFIG_PATH")) {
define("PP_CONFIG_PATH", __DIR__);
}
return $apiContext;
}
Can anyone help? Let me know if you need more info. Thanks up front.
I got the same problem too, I found that if any param was wrong (for example: an invalid card number or a invalid currency format), php SDK throw Connection Exception, Instead of returning certain Json Message(when I organize POST data myself and send with curl , It's OK)! I wander if it is reasonable to design like this, Or we just missed something!...