Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Payment Sandbox mode #658

Merged
merged 2 commits into from
Apr 21, 2017
Merged

Support Payment Sandbox mode #658

merged 2 commits into from
Apr 21, 2017

Conversation

skyred
Copy link
Contributor

@skyred skyred commented Apr 21, 2017

Following discussion from #507

This PR adds the feature. So, app user can set sandbox mode like this:

$app = new Application($options);
$wechat_pay = $app->payment;
$wechat_pay->enableSandbox(true);

Another option to enable to sandbox can be in $option:

    $options = [
      // 前面的appid什么的也得保留哦
      'app_id' => $appid,
      // ...
      // payment
      'payment' => [
        'merchant_id'        => $mch_id,
        'key'                => $key,
        'cert_path'          => 'path/to/your/cert.pem', // XXX: 绝对路径!!!!
        'key_path'           => 'path/to/your/key',      // XXX: 绝对路径!!!!
        'notify_url'         => $payment_gateway_plugin->getNotifyUrl()->toString(),
         'device_info'     => '013467007045764',
         'sub_app_id'      => '',
         'sub_merchant_id' => '',
         'sandbox_mode' => true,
        // ...
      ],
    ];

But, this PR does't include the second way. Further contribution is welcomed.

Comparing to the PR #657, this PR uses Github forking and patching best practice, and squashed the commits into one.

@overtrue
Copy link
Collaborator

我觉得是不是加一个方法来搞定 API 的封装会比较好呢?

protected $sandboxEnabled = false;
const API_HOST = 'https://api.mch.weixin.qq.com';

...


function sandboxMode($enabled = false) {
     $this->sandboxEnabled = $enabled;
}

...


function wrapApi($resource) {
  return self::API_HOST. ($this->sandboxEnabled ? '/sandbox' : '').$resource;
}


fetch api: $this->wrapApi(self:: API_PAY_ORDER);

@skyred
Copy link
Contributor Author

skyred commented Apr 21, 2017

我觉得是不是加一个方法来搞定 API 的封装会比较好呢?

在目前情况下,我没看出来有分别。但既然你建议了,我一会改过来

@@ -324,7 +321,7 @@ public function downloadBill($date, $type = self::BILL_TYPE_ALL)
*/
public function urlShorten($url)
{
return $this->request(self::API_URL_SHORTEN, ['long_url' => $url]);
return $this->request($this->wrapApi(self::API_URL_SHORTEN), ['long_url' => $url]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UrlShorten 没有 sandbox 模式吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

文档是这样写的
1、修改商户自有程序或配置中,微信支付api的链接,如:被扫支付官网的url为:https://api.mch.weixin.qq.com/pay/micropay增加sandbox路径,变更为https://api.mch.weixin.qq.com/sandbox/pay/micropay, 即可接入沙箱验收环境,其它接口类似; ---- https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=21_2

其它接口类似 让我以为是有的。

@skyred
Copy link
Contributor Author

skyred commented Apr 21, 2017

在测试都通过后,我会再次squash commits

@skyred
Copy link
Contributor Author

skyred commented Apr 21, 2017

Mockery文档上这样写的:

By default, all test doubles created with the Mockery::mock method will only accept calls that they have been configured to allow or expect.

所以,上面的Travis CI测试结果里说:

BadMethodCallException: Method Mockery_30_EasyWeChat_Payment_API::wrapApi() does not exist on this mock object

就是正确的。

但我不理解的是,PaymentAPITest.php 有很多
$api->prepare($order);, $api->pay($order);, $api->query('testTradeNoFoo'); 等也是没有allow or expect过,为什么它们不报错?

@overtrue
Copy link
Collaborator

@skyred protected 方法是默认不让 mock 的,除非你在创建测试对象的时候 ->shouldAllowMockingProtectedMethods() 让它可以被 mock。

@skyred
Copy link
Contributor Author

skyred commented Apr 21, 2017

考虑到之前API::****都是static, 所以我把 public function wrapApi改成public没有安全问题。tests都通过,我squash一下。

@@ -465,7 +465,7 @@ public function sandboxMode($enabled = false)
*
* @param string $resource
*/
protected function wrapApi($resource)
public function wrapApi($resource)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

额,没有这样的做法哦

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一般不会为了测试而修改源码为不标准写法的做法

Copy link
Contributor Author

@skyred skyred Apr 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我本来想$api->allow('wrapApi'); 但找了很多页面和官方文档,找不到相应的语句。后来想了一下wrapApi作为public也没什么坏处。虽然是为了测试而改代码,但是这个更改是我可以接收,因为之前的API::******的使用就是static的方法。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@skyred 哪里有静态方法哇?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

例如const API_PAY_ORDER = 'https://api.mch.weixin.qq.com/pay/micropay'; 以前可以静态获得$url = API:: API_PAY_ORDER 地址,意思是说这个地址不是封装在这个类里的。

现在,如果要获取一个endpoint URL:
可以:

$api = new API($merchant);
$api->sandboxMode(true);
$url = $api->wrapApi(API::API_PAY_ORDER);

如果是wrapApiprotected 的话,那就不一定在任何情况下都可以使用$api->wrapApi()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. wrapApi 并不是给 API.php 外界的类所使用的,不需要开放给外界
  2. const XXX 常量本来就是 public 的,毕竟它本身就是只读的,而方法不同
  3. 从一开始我就说了,你如果想在单元测试的时候让 wrapApi 能调用,你需要使用 mockery 提供的方法让 protected 方法可以 mock。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrapApi 并不是给 API.php 外界的类所使用的,不需要开放给外界

我上面的回复是,应该需要提供,因为旧的版本可以让外界拿到一个服务的URL, 从向后兼容的角度考虑,新的版本也需要提供一个方法让外界拿到一个服务的URL

从一开始我就说了,你如果想在单元测试的时候让 wrapApi 能调用,你需要使用 mockery 提供的方法让 protected 方法可以 mock。

我没有使用->shouldAllowMockingProtectedMethods(),因为这个方法会使API.class下的其他protected methods也可以被mock。我希望能找到一个方法可以只allow wrapApimock。但目前还没用在Mockery文档里找到。

这个PR对Maintainer的权限是开放的,你可以根据你的想法来最后决定如何设计,请直接commit到这个PR上来。

Fixing styleci complains.

More fixing on styles.

Use a wrapper for sandbox API instead.

More style fixing.

Still need one more line for styling.

Change the wrapApi to public.
@skyred
Copy link
Contributor Author

skyred commented Apr 21, 2017

7103067 是一个新的版本,我本来想 @overtrue 两个版本里选择一个他更喜欢的。但是,这个新的版本通过不了测试。Mockery文档缺乏,我暂时没有办法了。

@overtrue overtrue merged commit 0c66f95 into w7corp:master Apr 21, 2017
overtrue added a commit that referenced this pull request Apr 21, 2017
overtrue added a commit that referenced this pull request Apr 21, 2017
@skyred skyred deleted the patch-1 branch April 21, 2017 12:13
overtrue pushed a commit that referenced this pull request Apr 25, 2017
* 🚧Missing message handling

* Fix mini-program decryptor (#615)

* 🐛Fix mini-program decryptor

* fix styles

* 🚨Make the testcase works. (#616)

* Compatible with php5.5 (#617)

* Apply fixes from StyleCI (#618)

* 🚨 修复测试

* 🚨 修复测试

* Apply fixes from StyleCI (#621)

* phpunit path.

* Update OpenPlatform AppId

使用第三方平台授权来生成JS-SDK签名时,返回的 appid 是第三方平台的,应该改为授权方的 appid 才对。

* Add backers

* Add backers

* 修复新建卡券时, 填写高级信息时的字段缺失

点击查看[微信创建卡券文档](https://mp.weixin.qq.com/wiki?action=doc&id=mp1451025056&t=0.    3971944842969317#2.6)

* 添加获取微信支持的门店类目表

创建门店时,必须填入微信支持格式的门店类目, 所以需要先获得支持的门店类目
点击查看[微信创建门店文档](https://mp.weixin.qq.com/wiki?action=doc&id=mp1444378120&t=0.3682459036774999#mdlmb)

* 🔨 Refactoring for mini-program. (#632)

* Refactoring for mini-program.

* Fix styles.

* Fix styles again 💣

* Modify name.

* naming.

* PrefixedContainer Trait.

* ✨ Blacklist. (#634)

* Update README.md

* Apply fixes from StyleCI (#635)

* misspell

* modify oauth property (#639)

* formatting

* tweak code. (#640)

* tweak code.

* Fix styles.

* Remove unused method.

* ♻️ All tests have been namespaced. (#641)

* ♻️ All tests have been namespaced.

* ordered_use

* Fix styles.

* support cash coupon (#642)

* support cash coupon

* fixed styleci

* Code cleanup & refactoring. (#646)

* Rename.

* Open-platform api tests.

* Sensitive config items.

* Socialite minimum version.

* Log Configuration.

* Add header.

* Remove include.

* Log configuration.

* Header copyright.

* Remove open-platform option.

* array type.

* Use short array syntax.

* remove files.

* Update open-platform service provider.

* Remove verify-ticket trait.

* Remove trait.

* do nothing for the time being.

* Update doc.

* use `basename` function

* Cache.

* refactoring

* `Daemon` => `Authorization`

* Styles.

* Update code for open-platform (#649)

* Wrong role

* full name

* Add PrefixedContainer testcase.

* Add fetch method.

* Fix.

* announced api

* Remove test

* extract method.

* Update test.

* fix bug

* remove method.

* get api.

* Styles

* new line

* Update PreAuthorization.php

* Merge from open-platform branch. (#651)

* Remove stale code.

* Full namespace.

* protected vars.

* Cleanup

* Do nothing on the auth events.

* tweak.

* Remove @method announce

* rename.

* Unused code

* Update PrefixedContainerTest.php

* optimizes (#652)

* variable name shortening.

* Add callable.

* class name

* 🐛 开放平台 ServerGuard 覆盖基类 ServerGuard

* extensible

* Mini program datacube. (#655)

* mini-program datacube.

* stats testcase.

* service provider.

* Apply fixes from StyleCI (#656)

* avoid ambiguity. (#659)

* Support Payment Sandbox mode (#658)

* Support Payment Sandbox.

Fixing styleci complains.

More fixing on styles.

Use a wrapper for sandbox API instead.

More style fixing.

Still need one more line for styling.

Change the wrapApi to public.

* Different approach; allow mocking protected methods.

* Fix tests for #658

* Cleanup. #658

* Fix payment tools API (#660)

* Fix.

* Fix.

* Fix styles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants