Skip to content

Commit cfde75f

Browse files
Merge branch 'release/1.12.0'
Release 1.12.0
2 parents be64573 + 147762d commit cfde75f

File tree

130 files changed

+3004
-364
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+3004
-364
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# Change Log
22

3+
## [Unreleased](https://github.com/bunq/sdk_php/tree/HEAD)
4+
5+
[Full Changelog](https://github.com/bunq/sdk_php/compare/1.10.16...HEAD)
6+
7+
**Closed issues:**
8+
9+
- Fout! Use of undefined constant CURLOPT\_PINNEDPUBLICKEY - assumed 'CURLOPT\_PINNEDPUBLICKEY' \(this will throw an Error in a future version of PHP\) [\#178](https://github.com/bunq/sdk_php/issues/178)
10+
- NotificationFilterUrlMonetaryAccount::create fails [\#177](https://github.com/bunq/sdk_php/issues/177)
11+
- TransferwiseTransfer property on EventObject is not populated [\#176](https://github.com/bunq/sdk_php/issues/176)
12+
- Bad schedule payment update response\(sdk\_php\) [\#173](https://github.com/bunq/sdk_php/issues/173)
13+
- Allow access to `merchant\_category\_code` in the `counterparty\_alias` [\#171](https://github.com/bunq/sdk_php/issues/171)
14+
- Not receive schedule payment status \(sdk\_php\) [\#170](https://github.com/bunq/sdk_php/issues/170)
15+
16+
**Merged pull requests:**
17+
18+
- Fix NotificationFilter, Model issues and implement PSD2 [\#179](https://github.com/bunq/sdk_php/pull/179) ([NickvandeGroes](https://github.com/NickvandeGroes))
19+
20+
## [1.10.16](https://github.com/bunq/sdk_php/tree/1.10.16) (2019-06-15)
21+
[Full Changelog](https://github.com/bunq/sdk_php/compare/1.10.2...1.10.16)
22+
323
## [1.10.2](https://github.com/bunq/sdk_php/tree/1.10.2) (2019-05-15)
424
[Full Changelog](https://github.com/bunq/sdk_php/compare/1.10.1...1.10.2)
525

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,30 @@ BunqContext::loadApiContext($apiContext);
8484

8585
**Tip:** both saving and restoring the context can be done without any arguments. In this case the context will be saved to/restored from the `bunq.conf` file in the same folder with your script.
8686

87+
##### PSD2
88+
It is possible to create an ApiContext as PSD2 Service Provider. Although this might seem a complex task, we wrote some helper implementations to get you started.
89+
You need to create a certificate and private key to get you started. Our sandbox environment currently accepts all certificates, if these criteria are met:
90+
- Up to 64 characters
91+
- PISP and/or AISP used in the end.
92+
93+
Make sure you have your unique eIDAS certificate number and certificates ready when you want to perform these tasks on our production environment.
94+
95+
Creating a PSD2 context is very easy:
96+
```php
97+
$apiContext = ApiContext::createForPsd2(
98+
BunqEnumApiEnvironmentType::SANDBOX(), // Could be PRODUCTION as well.
99+
SecurityUtil::getCertificateFromFile($pathToCertificate),
100+
SecurityUtil::getPrivateKeyFromFile($pathToKey),
101+
[
102+
SecurityUtil::getCertificateFromFile($pathToCertificateInChain), // Could be one file containing chain, or multiple certificate files in array.
103+
],
104+
$description
105+
)
106+
```
107+
108+
This context can be saved the same way as a normal ApiContext. After creating this context, create an OAuth client to get your users to grant you access.
109+
For a more detailed example, check the [tinker_php](https://github.com/bunq/tinker_php/) repository.
110+
87111
##### Proxy
88112
You can use a proxy with the bunq PHP SDK. This option must be a string. This proxy will be used for all requests done with
89113
the context for which it was provided. You will be prompted to provide a proxy URL when using the interactive installation script.
@@ -127,6 +151,18 @@ Payment::create(
127151
##### Example
128152
See [`tinker/BunqLib`](https://github.com/bunq/tinker_php/blob/05a38a2660e6f6db1f7efc9b915f0131c172c230/src/BunqLib.php#L240-L245)
129153

154+
##### NotificationFilters / Callbacks
155+
**Note!** Due to an in internal change in the way we handle `NotificationFilters` (Callbacks), you should not use the default classes included in this SDK.
156+
Please make sure you make use of the associated `Internal`-classes. For example when you need `NotificationFilterUrlUser`, make use of `NotificationFilterUrlUserInternal`.
157+
You can use every method of these classes, except for the `create()` method. **Always use `createWithListResponse()` instead.**
158+
159+
##### Example
160+
```
161+
NotificationFilterPushUserInternal::createWithListResponse(...)
162+
NotificationFilterUrlUserInternal::createWithListResponse(...)
163+
NotificationFilterUrlMonetaryAccountInternal::createWithListResponse(...)
164+
```
165+
130166
#### Reading objects
131167
To use the read method you must pass the identifier of the object to read (ID or UUID) except for the endpoints `User`, `UserPerson`, `UserCompany` and `MonetaryAccount`. The SDK will use the default IDs when none are passed. For all other endpoints you must pass the identifier.
132168

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"phpstan/phpstan": "^0.8",
4545
"phpunit/phpunit": "^6.0.13",
4646
"sebastian/phpcpd": "^3.0",
47-
"sensiolabs/security-checker": "^4.1"
47+
"sensiolabs/security-checker": "^5.0"
4848
},
4949
"bin": [
5050
"bin/bunq-install"

grumphp.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ parameters:
77
ignore_unstaged_changes: false
88
process_async_limit: 10
99
process_async_wait: 1000
10-
process_timeout: 120
10+
process_timeout: 300
1111
stop_on_failure: true
1212
ascii:
1313
failed: ~

phpunit.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
<testsuite name="ParaTest Fixtures">
88
<directory>./tests/</directory>
99
</testsuite>
10-
</testsuites>
11-
<testsuites>
1210
<testsuite name="Test Suite">
1311
<directory>./tests</directory>
1412
</testsuite>

src/Context/ApiContext.php

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
use bunq\Exception\BunqException;
55
use bunq\Model\Core\DeviceServerInternal;
66
use bunq\Model\Core\Installation;
7+
use bunq\Model\Core\PaymentServiceProviderCredentialInternal;
78
use bunq\Model\Core\SandboxUserInternal;
89
use bunq\Model\Core\SessionServer;
910
use bunq\Model\Core\Token;
1011
use bunq\Model\Generated\Endpoint\Session;
12+
use bunq\Model\Generated\Object\Certificate;
1113
use bunq\Security\KeyPair;
14+
use bunq\Security\PrivateKey;
1215
use bunq\Util\BunqEnumApiEnvironmentType;
1316
use bunq\Util\FileUtil;
1417
use bunq\Util\InstallationUtil;
18+
use bunq\Util\SecurityUtil;
1519
use GuzzleHttp\Psr7\Uri;
1620

1721
/**
@@ -117,6 +121,46 @@ public static function create(
117121
return $apiContext;
118122
}
119123

124+
/**
125+
* @param BunqEnumApiEnvironmentType $environmentType
126+
* @param Certificate $publicCertificate
127+
* @param PrivateKey $privateKey
128+
* @param Certificate[] $allChainCertificate
129+
* @param string $description
130+
* @param string[] $allPermittedIp
131+
* @param string|null $proxyUrl
132+
*
133+
* @return ApiContext
134+
*/
135+
public static function createForPsd2(
136+
BunqEnumApiEnvironmentType $environmentType,
137+
Certificate $publicCertificate,
138+
PrivateKey $privateKey,
139+
array $allChainCertificate,
140+
string $description,
141+
array $allPermittedIp = [],
142+
string $proxyUrl = null
143+
): ApiContext {
144+
InstallationUtil::assertDeviceDescriptionIsValid($description);
145+
InstallationUtil::assertAllIpIsValid($allPermittedIp);
146+
147+
$apiContext = new static();
148+
$apiContext->environmentType = $environmentType;
149+
$apiContext->proxyUrl = $proxyUrl;
150+
151+
$apiContext->initializeInstallationContext();
152+
$apiContext->initializePsd2Credential(
153+
$publicCertificate,
154+
$privateKey,
155+
$allChainCertificate
156+
);
157+
158+
$apiContext->registerDevice($description, $allPermittedIp);
159+
$apiContext->initializeSessionContext();
160+
161+
return $apiContext;
162+
}
163+
120164
/**
121165
*/
122166
private function createSandboxUser()
@@ -152,6 +196,34 @@ private function initializeInstallationContext()
152196
);
153197
}
154198

199+
/**
200+
* @param Certificate $publicCertificate
201+
* @param PrivateKey $privateKey
202+
* @param Certificate[] $allChainCertificate
203+
*/
204+
private function initializePsd2Credential(
205+
Certificate $publicCertificate,
206+
PrivateKey $privateKey,
207+
array $allChainCertificate
208+
) {
209+
$sessionToken = $this->installationContext->getInstallationToken();
210+
$clientKeyPair = $this->installationContext->getKeyPairClient();
211+
212+
$stringToSign = SecurityUtil::getPublicKeyFormattedString(
213+
$clientKeyPair->getPublicKey()
214+
) . $sessionToken->getToken();
215+
216+
$keySignature = $privateKey->sign($stringToSign);
217+
$paymentProviderResponse = PaymentServiceProviderCredentialInternal::createWithApiContext(
218+
$publicCertificate->getCertificate(),
219+
SecurityUtil::getCertificateChainString($allChainCertificate),
220+
$keySignature,
221+
$this
222+
);
223+
224+
$this->apiKey = $paymentProviderResponse->getValue()->getTokenValue();
225+
}
226+
155227
/**
156228
* @param string $description
157229
* @param string[] $permittedIps
@@ -183,7 +255,7 @@ private function initializeSessionContext()
183255
*/
184256
public static function restore(string $fileName = self::FILENAME_CONFIG_DEFAULT): ApiContext
185257
{
186-
$contextJsonString = self::getContextJsonString($fileName);
258+
$contextJsonString = static::getContextJsonString($fileName);
187259

188260
return static::fromJson($contextJsonString);
189261
}

src/Context/BunqContext.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
use bunq\Exception\BunqException;
55

6+
/**
7+
*/
68
class BunqContext
79
{
810
/**

src/Context/UserContext.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33

44
use bunq\Exception\BunqException;
55
use bunq\Model\Core\BunqModel;
6-
use bunq\Model\Core\SessionServer;
76
use bunq\Model\Generated\Endpoint\MonetaryAccountBank;
87
use bunq\Model\Generated\Endpoint\User;
98
use bunq\Model\Generated\Endpoint\UserApiKey;
109
use bunq\Model\Generated\Endpoint\UserCompany;
10+
use bunq\Model\Generated\Endpoint\UserPaymentServiceProvider;
1111
use bunq\Model\Generated\Endpoint\UserPerson;
1212

13+
/**
14+
*/
1315
class UserContext
1416
{
1517
/**
@@ -46,6 +48,11 @@ class UserContext
4648
*/
4749
protected $userApiKey;
4850

51+
/**
52+
* @var UserPaymentServiceProvider
53+
*/
54+
protected $userPaymentServiceProvider;
55+
4956
/**
5057
* @var MonetaryAccountBank
5158
*/
@@ -85,6 +92,8 @@ private function setUser($user)
8592
$this->userCompany = $user;
8693
} elseif ($user instanceof UserApiKey) {
8794
$this->userApiKey = $user;
95+
} elseif ($user instanceof UserPaymentServiceProvider) {
96+
$this->userPaymentServiceProvider = $user;
8897
} else {
8998
throw new BunqException(vsprintf(self::ERROR_UNEXPECTED_USER_INSTANCE, [get_class($user)]));
9099
}
@@ -95,6 +104,10 @@ private function setUser($user)
95104
*/
96105
public function initMainMonetaryAccount()
97106
{
107+
if (!is_null($this->userPaymentServiceProvider)) {
108+
return;
109+
}
110+
98111
$allMonetaryAccount = MonetaryAccountBank::listing()->getValue();
99112

100113
foreach ($allMonetaryAccount as $account) {

src/Exception/BadRequestException.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
*/
66
class BadRequestException extends ApiException
77
{
8-
98
}

src/Exception/ForbiddenException.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
*/
66
class ForbiddenException extends ApiException
77
{
8-
98
}

0 commit comments

Comments
 (0)