Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mutualize services
Browse files Browse the repository at this point in the history
odolbeau committed Apr 4, 2024
1 parent 8f3ae7c commit 26cdc2d
Showing 18 changed files with 706 additions and 268 deletions.
38 changes: 35 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -10,13 +10,30 @@ composer require doskyft/helloasso-php

## Utilisation

Pour commencer, il faut créer une instance de `HelloassoClient`.

```php
$helloasso = new HelloassoClient(
use Helloasso\HelloassoClientFactory;

$helloassoClient = HelloassoClientFactory::create(
'hello_asso_id',
'hello_asso_secret',
'hello_asso_organization_slug',
true # sandbox
);
```

Maintenant, on peut commencer à utiliser le client

### CheckoutIntent

<details>

<summary>Créer un CheckoutIntent</summary>

```php
use Helloasso\Models\Carts\CheckoutPayer;
use Helloasso\Models\Carts\InitCheckoutBody;

$checkoutIntent = (new InitCheckoutBody())
->setTotalAmount(1000)
@@ -35,8 +52,23 @@ $checkoutIntent = (new InitCheckoutBody())
])
;

$helloasso->checkout->create($checkoutIntent);
$helloassoClient->checkout->create($checkoutIntent);
```
[Voir la documentation](https://api.helloasso.com/v5/swagger/ui/index#/Checkout%20intents%20management/OrganizationCheckoutIntents_PostInitCheckout)
</details>

### Évènements

<details>

<summary></summary>

```php
use Helloasso\Models\Event;

$event = $helloassoClient->decodeEvent($rawEventReceivedFromHelloasso); // Returns an instance of Event
```
</details>

## Contributeurs

@@ -67,4 +99,4 @@ $helloasso->checkout->create($checkoutIntent);
</a>
</td>
</tr>
</table>
</table>
61 changes: 50 additions & 11 deletions src/HelloassoClient.php
Original file line number Diff line number Diff line change
@@ -4,26 +4,65 @@

namespace Helloasso;

use Helloasso\Exception\InvalidValueException;
use Helloasso\Http\ApiCaller;
use Helloasso\Models\Event;
use Helloasso\Models\Forms\FormPublicModel;
use Helloasso\Models\Statistics\OrderDetail;
use Helloasso\Models\Statistics\PaymentDetail;
use Helloasso\Service\CheckoutIntentService;
use Helloasso\Service\DirectoryService;
use Helloasso\Service\EventService;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerInterface;

class HelloassoClient
{
public CheckoutIntentService $checkout;

public DirectoryService $directory;

public EventService $event;

public function __construct(
readonly string $clientId,
readonly string $clientSecret,
readonly string $organizationSlug,
readonly bool $sandbox = false,
private readonly SerializerInterface|DenormalizerInterface $serializer,
ApiCaller $apiCaller,
string $organizationSlug,
) {
$this->checkout = new CheckoutIntentService($clientId, $clientSecret, $organizationSlug, $sandbox);
$this->directory = new DirectoryService($clientId, $clientSecret, $organizationSlug, $sandbox);
$this->event = new EventService($clientId, $clientSecret, $organizationSlug, $sandbox);
$this->checkout = new CheckoutIntentService($apiCaller, $organizationSlug);
$this->directory = new DirectoryService();
}

/**
* Decode an Helloasso event content (webhook).
*
* @throws InvalidValueException
*/
public function decodeEvent(string $eventData): Event
{
try {
$event = json_decode($eventData, true, 512, \JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
throw new InvalidValueException('Unable to json_decode given event.');
}

$eventType = $event['eventType'] ?? null;
if (null === $eventType) {
throw new InvalidValueException('No eventType key found in given event.');
}

$data = $event['data'] ?? null;
if (null === $data) {
throw new InvalidValueException('No data key found in given event.');
}

$expectedModel = match ($eventType) {
Event::EVENT_TYPE_FORM => FormPublicModel::class,
Event::EVENT_TYPE_ORDER => OrderDetail::class,
Event::EVENT_TYPE_PAYMENT => PaymentDetail::class,
default => throw new InvalidValueException('eventType "'.$eventType.'" not supported')
};

return (new Event())
->setMetadata($event['metadata'] ?? [])
->setData($this->serializer->denormalize($data, $expectedModel))
->setEventType($eventType)
;
}
}
59 changes: 59 additions & 0 deletions src/HelloassoClientFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Helloasso;

use Helloasso\Http\ApiCaller;
use Helloasso\Http\ResponseHandler;
use Helloasso\Http\TokenManager;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

class HelloassoClientFactory
{
public static function create(
string $clientId,
string $clientSecret,
string $organizationSlug,
bool $sandbox = false,
): HelloassoClient {
$httpClient = HttpClient::createForBaseUri($sandbox ? 'https://api.helloasso-sandbox.com' : 'https://api.helloasso.com', [
'headers' => [
'accept' => 'application/json',
'Content-type: application/json',
],
]);
$serializer = self::createSerializer();
$responseHandler = new ResponseHandler($serializer);
$tokenManager = new TokenManager($httpClient, $responseHandler, $clientId, $clientSecret);

return new HelloassoClient(
$serializer,
new ApiCaller($httpClient, $tokenManager, $responseHandler, $serializer),
$organizationSlug,
);
}

private static function createSerializer(): Serializer
{
$encoder = [new JsonEncoder()];
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$normalizer = [
new DateTimeNormalizer(),
new BackedEnumNormalizer(),
new ArrayDenormalizer(),
new ObjectNormalizer(null, null, null, $extractor),
];

return new Serializer($normalizer, $encoder);
}
}
54 changes: 54 additions & 0 deletions src/Http/ApiCaller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Helloasso\Http;

use Helloasso\Models\HelloassoObject;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\Serializer;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class ApiCaller
{
public function __construct(
private readonly HttpClientInterface $httpClient,
private readonly TokenManager $tokenManager,
private readonly ResponseHandler $responseHandler,
private readonly Serializer $serializer,
) {
}

/**
* @template T of HelloassoObject
*
* @param class-string<T> $responseClassType
*
* @return T
*/
public function post(string $url, array|HelloassoObject|null $body, string $responseClassType): HelloassoObject
{
$response = $this->httpClient->request(Request::METHOD_POST, $url, [
'auth_bearer' => $this->tokenManager->getAccessToken(),
'body' => $this->serializer->serialize($body, 'json'),
]);

return $this->responseHandler->deserializeResponse($response, $responseClassType);
}

/**
* @template T of HelloassoObject
*
* @param class-string<T> $responseClassType
*
* @return T
*/
public function get(string $url, string $responseClassType): HelloassoObject
{
$response = $this->httpClient->request(Request::METHOD_GET, $url, [
'auth_bearer' => $this->tokenManager->getAccessToken(),
]);

return $this->responseHandler->deserializeResponse($response, $responseClassType);
}
}
58 changes: 58 additions & 0 deletions src/Http/ResponseHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Helloasso\Http;

use Helloasso\Exception\HelloassoApiException;
use Helloasso\Models\HelloassoObject;
use Symfony\Component\Serializer\Serializer;
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

class ResponseHandler
{
public function __construct(
private readonly Serializer $serializer,
) {
}

/**
* @template T of HelloassoObject
*
* @param class-string<T> $responseClassType
*
* @return T
*
* @throws HelloassoApiException
*/
public function deserializeResponse(ResponseInterface $response, string $responseClassType): HelloassoObject
{
try {
$responseContent = $response->getContent();
} catch (HttpExceptionInterface|TransportExceptionInterface $e) {
try {
$content = $response->getContent(false);
} catch (HttpExceptionInterface|TransportExceptionInterface $e) {
$content = 'unknown error';
}

throw new HelloassoApiException($e->getMessage().' : '.$content);
}

return $this->deserializeResponseContent($responseContent, $responseClassType);
}

/**
* @template T of HelloassoObject
*
* @param class-string<T> $responseClassType
*
* @return T
*/
public function deserializeResponseContent(string $content, string $responseClassType): HelloassoObject
{
return $this->serializer->deserialize($content, $responseClassType, 'json');
}
}
49 changes: 49 additions & 0 deletions src/Http/TokenManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Helloasso\Http;

use Helloasso\Models\ClientCredentials;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class TokenManager
{
private ?string $accessToken = null;

public function __construct(
private readonly HttpClientInterface $httpClient,
private readonly ResponseHandler $responseHandler,
private readonly string $clientId,
private readonly string $clientSecret,
) {
}

public function getAccessToken(): string
{
if (null === $this->accessToken) {
$this->retrieveAccessToken();
}

return $this->accessToken;
}

private function retrieveAccessToken(): void
{
$response = $this->httpClient->request(Request::METHOD_POST, '/oauth2/token', [
'body' => [
'grant_type' => 'client_credentials',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
],
'headers' => [
'Content-Type: application/x-www-form-urlencoded',
],
]);

$credentials = $this->responseHandler->deserializeResponse($response, ClientCredentials::class);

$this->accessToken = $credentials->getAccessToken();
}
}
4 changes: 2 additions & 2 deletions src/Models/Forms/TierPublicModel.php
Original file line number Diff line number Diff line change
@@ -98,9 +98,9 @@ public function getVatRate(): float
return $this->vatRate;
}

public function setVatRate(float $vatRate): self
public function setVatRate(float|int $vatRate): self
{
$this->vatRate = $vatRate;
$this->vatRate = (float) $vatRate;

return $this;
}
121 changes: 0 additions & 121 deletions src/Service/ApiRequest.php

This file was deleted.

47 changes: 12 additions & 35 deletions src/Service/CheckoutIntentService.php
Original file line number Diff line number Diff line change
@@ -5,59 +5,36 @@
namespace Helloasso\Service;

use Helloasso\Exception\HelloassoApiException;
use Helloasso\Http\ApiCaller;
use Helloasso\Models\Carts\CheckoutIntentResponse;
use Helloasso\Models\Carts\InitCheckoutBody;
use Helloasso\Models\Carts\InitCheckoutResponse;
use Symfony\Component\HttpFoundation\Request;

class CheckoutIntentService extends ApiRequest
class CheckoutIntentService
{
public const CREATE_ENDPOINT = '/v5/organizations/%s/checkout-intents';
public const RETRIEVE_ENDPOINT = '/v5/organizations/%s/checkout-intents/%d';
public function __construct(
private readonly ApiCaller $apiCaller,
private readonly string $organizationSlug,
) {
}

/**
* @throws HelloassoApiException
*/
public function create(InitCheckoutBody $checkoutIntent): InitCheckoutResponse
{
$params = [
'auth_bearer' => $this->oauth()->getAccessToken(),
'body' => $this->serialize($checkoutIntent),
'headers' => [
'Content-type: application/json',
],
];

$request = $this->request(
Request::METHOD_POST,
$this->getBaseUrl().sprintf(self::CREATE_ENDPOINT, $this->organizationSlug),
$params
);

/** @var InitCheckoutResponse $content */
$content = $this->deserialize($this->getContent($request), InitCheckoutResponse::class);

return $content;
$url = sprintf('/v5/organizations/%s/checkout-intents', $this->organizationSlug);

return $this->apiCaller->post($url, $checkoutIntent, InitCheckoutResponse::class);
}

/**
* @throws HelloassoApiException
*/
public function retrieve(int $checkoutIntentId): CheckoutIntentResponse
{
$params = [
'auth_bearer' => $this->oauth()->getAccessToken(),
];

$request = $this->request(
Request::METHOD_GET,
$this->getBaseUrl().sprintf(self::RETRIEVE_ENDPOINT, $this->organizationSlug, $checkoutIntentId),
$params
);

/** @var CheckoutIntentResponse $content */
$content = $this->deserialize($this->getContent($request), CheckoutIntentResponse::class);
$url = sprintf('/v5/organizations/%s/checkout-intents/%d', $this->organizationSlug, $checkoutIntentId);

return $content;
return $this->apiCaller->get($url, CheckoutIntentResponse::class);
}
}
2 changes: 1 addition & 1 deletion src/Service/DirectoryService.php
Original file line number Diff line number Diff line change
@@ -4,6 +4,6 @@

namespace Helloasso\Service;

class DirectoryService extends ApiRequest
class DirectoryService
{
}
58 changes: 0 additions & 58 deletions src/Service/EventService.php

This file was deleted.

25 changes: 25 additions & 0 deletions tests/Functional/FunctionalTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Helloasso\Tests\Functional;

use Helloasso\HelloassoClient;
use Helloasso\HelloassoClientFactory;
use PHPUnit\Framework\TestCase;

abstract class FunctionalTestCase extends TestCase
{
protected function getClient(): HelloassoClient
{
$clientId = getenv('HELLOASSO_CLIENT_ID');
$clientSecret = getenv('HELLOASSO_CLIENT_SECRET');
$organisationSlug = getenv('HELLOASSO_ORGANISATION') ? getenv('HELLOASSO_ORGANISATION_SLUG') : 'helloasso-php-sdk';

if (empty($clientId) || empty($clientSecret)) {
throw new \RuntimeException('Some mandatory environment variables ("HELLOASSO_CLIENT_ID", "HELLOASSO_CLIENT_SECRET") have not been set (or incorrectly set). Please consider creating an account on https://www.helloasso-sandbox.com/ and run tests using HELLOASSO_CLIENT_ID=[YourClientId] HELLOASSO_CLIENT_SECRET=[YourClientSecret] HELLOASSO_ORGANISATION_SLUG=[YourOrganisation] vendor/bin/phpunit');
}

return HelloassoClientFactory::create($clientId, $clientSecret, $organisationSlug, true);
}
}
40 changes: 40 additions & 0 deletions tests/Functional/HelloAssoClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Helloasso\Tests\Functional;

use Helloasso\Models\Event;
use Helloasso\Models\Forms\FormPublicModel;
use Helloasso\Models\Statistics\OrderDetail;
use Helloasso\Models\Statistics\PaymentDetail;

final class HelloAssoClientTest extends FunctionalTestCase
{
public function testDecodeOrderEvent(): void
{
$event = $this->getClient()->decodeEvent(file_get_contents(__DIR__.'/../fixtures/event.Order.json'));

$this->assertInstanceOf(Event::class, $event);
$this->assertSame('Order', $event->getEventType());
$this->assertInstanceOf(OrderDetail::class, $event->getData());
}

public function testDecodePaymentEvent(): void
{
$event = $this->getClient()->decodeEvent(file_get_contents(__DIR__.'/../fixtures/event.Payment.json'));

$this->assertInstanceOf(Event::class, $event);
$this->assertSame('Payment', $event->getEventType());
$this->assertInstanceOf(PaymentDetail::class, $event->getData());
}

public function testDecodeFormEvent(): void
{
$event = $this->getClient()->decodeEvent(file_get_contents(__DIR__.'/../fixtures/event.Form.json'));

$this->assertInstanceOf(Event::class, $event);
$this->assertSame('Form', $event->getEventType());
$this->assertInstanceOf(FormPublicModel::class, $event->getData());
}
}
14 changes: 8 additions & 6 deletions tests/Functional/Service/CheckoutIntentServiceTest.php
Original file line number Diff line number Diff line change
@@ -4,17 +4,16 @@

namespace Helloasso\Tests\Functional\Service;

use Helloasso\Models\Carts\CheckoutIntentResponse;
use Helloasso\Models\Carts\CheckoutPayer;
use Helloasso\Models\Carts\InitCheckoutBody;
use Helloasso\Models\Carts\InitCheckoutResponse;
use Helloasso\Service\CheckoutIntentService;
use Helloasso\Tests\Functional\FunctionalTestCase;

final class CheckoutIntentServiceTest extends ServiceTestCase
final class CheckoutIntentServiceTest extends FunctionalTestCase
{
public function testCreate(): void
public function testCreateAndRetrieve(): void
{
$service = $this->createService(CheckoutIntentService::class);

$payer = new CheckoutPayer();
$payer
->setFirstName('Greta')
@@ -33,8 +32,11 @@ public function testCreate(): void
->setPayer($payer)
;

$response = $service->create($body);
$response = $this->getClient()->checkout->create($body);

$this->assertInstanceOf(InitCheckoutResponse::class, $response);

$response = $this->getClient()->checkout->retrieve($response->getId());
$this->assertInstanceOf(CheckoutIntentResponse::class, $response);
}
}
31 changes: 0 additions & 31 deletions tests/Functional/Service/ServiceTestCase.php

This file was deleted.

105 changes: 105 additions & 0 deletions tests/fixtures/event.Form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"data": {
"organizationLogo": "https://cdn.helloasso.com/img/logos/association logo example.jpg",
"organizationName": "Association Exemple",
"tiers": [
{
"id": 1,
"label": "mon tarif 1",
"description": "description 1",
"tierType": "Registration",
"price": 1000,
"vatRate": 0,
"paymentFrequency": "Single",
"maxPerUser": 5,
"isEligibleTaxReceipt": true
},
{
"id": 2,
"label": "mon tarif 2",
"description": "description 2",
"tierType": "Registration",
"price": 1000,
"vatRate": 0,
"paymentFrequency": "Single",
"maxPerUser": 5,
"isEligibleTaxReceipt": true
},
{
"id": 3,
"label": "mon tarif 3",
"description": "description 3",
"tierType": "Registration",
"price": 1000,
"vatRate": 0,
"paymentFrequency": "Single",
"maxPerUser": 5,
"isEligibleTaxReceipt": true
},
{
"id": 4,
"label": "mon tarif 4",
"description": "description 4",
"tierType": "Registration",
"price": 1000,
"vatRate": 0,
"paymentFrequency": "Single",
"maxPerUser": 5,
"isEligibleTaxReceipt": true
},
{
"id": 5,
"label": "mon tarif 5",
"description": "description 5",
"tierType": "Registration",
"price": 1000,
"vatRate": 0,
"paymentFrequency": "Single",
"maxPerUser": 5,
"isEligibleTaxReceipt": true
}
],
"activityType": "ActivityType",
"activityTypeId": 12,
"place": {
"address": "23 rue du palmier",
"name": "Café du théatre",
"city": "Paris",
"zipCode": "75000",
"country": "FRA",
"geoLocation": {
"latitude": 22.56,
"longitude": 44.87
}
},
"saleEndDate": "2024-04-06T23:12:53.5983212+02:00",
"saleStartDate": "2024-04-02T23:12:53.5983212+02:00",
"banner": {
"fileName": "thumbnail 1",
"publicUrl": "https://cdn.helloasso.com/img/photos/evenements/thumbnail 1"
},
"currency": "EUR",
"description": "Description de mon événement",
"startDate": "2024-04-04T23:05:53.5983212+02:00",
"endDate": "2024-04-11T23:12:53.5983212+02:00",
"logo": {
"fileName": "image 1",
"publicUrl": "https://cdn.helloasso.com/img/photos/evenements/image 1"
},
"meta": {
"createdAt": "2024-04-04T22:57:53.5983212+02:00",
"updatedAt": "2024-04-04T22:57:53.5983212+02:00"
},
"state": "Public",
"title": "Nom de mon événement",
"widgetButtonUrl": "https://www.helloasso.com/associations/association-exemple/evenements/formulaire-exemple/widget-bouton",
"widgetFullUrl": "https://www.helloasso.com/associations/association-exemple/evenements/formulaire-exemple/widget",
"widgetVignetteHorizontalUrl": "https://www.helloasso.com/associations/association-exemple/evenements/formulaire-exemple/widget-vignette-horizontale",
"widgetVignetteVerticalUrl": "https://www.helloasso.com/associations/association-exemple/evenements/formulaire-exemple/widget-vignette",
"formSlug": "formulaire-exemple",
"formType": "Event",
"url": "https://www.helloasso.com/associations/association-exemple/evenements/formulaire-exemple",
"organizationSlug": "association-exemple"
},
"eventType": "Form"
}
145 changes: 145 additions & 0 deletions tests/fixtures/event.Order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"data": {
"order": {
"id": 12578,
"date": "2019-12-15T17:27:02+01:00",
"formSlug": "formulaire-exemple",
"formType": "Event",
"organizationName": "name",
"organizationSlug": "association-exemple",
"organizationType": "Association1901",
"organizationIsUnderColucheLaw": false,
"formName": "name",
"meta": {
"createdAt": "2019-12-15T17:27:02+01:00",
"updatedAt": "2019-12-15T17:27:02+01:00"
},
"isAnonymous": false,
"isAmountHidden": false
},
"payer": {
"email": "john.doe@test.com",
"address": "23 rue du palmier",
"city": "Paris",
"zipCode": "75000",
"country": "FRA",
"company": "Hello Asso",
"dateOfBirth": "1986-07-06T00:00:00+02:00",
"firstName": "John",
"lastName": "Doe"
},
"payments": [
{
"cashOutState": "CashedOut",
"shareAmount": 10000,
"id": 159875,
"amount": 11000,
"date": "2019-12-15T17:27:02+01:00",
"paymentMeans": "Card",
"installmentNumber": 1,
"state": "Authorized",
"meta": {
"createdAt": "2019-12-15T17:27:02+01:00",
"updatedAt": "2019-12-15T17:27:02+01:00"
}
},
{
"cashOutState": "Transfered",
"shareAmount": 30000,
"id": 159876,
"amount": 9000,
"date": "2020-01-15T17:27:02+01:00",
"paymentMeans": "Card",
"installmentNumber": 2,
"state": "Authorized",
"meta": {
"createdAt": "2020-01-15T17:27:02+01:00",
"updatedAt": "2020-01-15T17:27:02+01:00"
}
},
{
"shareAmount": 30000,
"id": 159877,
"amount": 9000,
"date": "2020-02-15T17:27:02+01:00",
"paymentMeans": "Card",
"installmentNumber": 3,
"state": "Pending",
"meta": {
"createdAt": "2020-02-15T17:27:02+01:00",
"updatedAt": "2020-02-15T17:27:02+01:00"
},
"refundOperations": [
{
"id": 1,
"amount": 2000,
"amountTip": 200,
"status": "PROCESSED",
"meta": {
"createdAt": "2024-04-02T10:16:24.0205634+02:00",
"updatedAt": "2024-04-03T10:16:24.0205634+02:00"
}
}
]
}
],
"name": "Adhesion Football",
"user": {
"firstName": "John",
"lastName": "Doe"
},
"priceCategory": "Fixed",
"discount": {
"code": "DISC30 : -30€",
"amount": 3000
},
"customFields": [
{
"id": 0,
"name": "BirthDate",
"type": "Date",
"answer": "1978-09-15"
},
{
"id": 0,
"name": "ZipCode",
"type": "Zipcode",
"answer": "33600"
}
],
"options": [
{
"name": "T-Shirt",
"amount": 700,
"priceCategory": "Fixed",
"isRequired": false,
"customFields": [
{
"id": 0,
"name": "Couleur",
"type": "ChoiceList",
"answer": "Bleue"
}
],
"optionId": 12581
},
{
"name": "Casquette",
"amount": 300,
"priceCategory": "Fixed",
"isRequired": false,
"optionId": 12580
}
],
"qrCode": "MTI1Nzg6NjM3MTIwMjQwMjIwMDAwMDAw",
"tierDescription": "tierDescription",
"tierId": 168965,
"comment": "comment",
"id": 12578,
"amount": 30000,
"type": "Membership",
"initialAmount": 30000,
"state": "Processed"
},
"eventType": "Order"
}
63 changes: 63 additions & 0 deletions tests/fixtures/event.Payment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"data": {
"order": {
"id": 12578,
"date": "2019-12-15T17:27:02+01:00",
"formSlug": "formulaire-exemple",
"formType": "Event",
"organizationName": "name",
"organizationSlug": "association-exemple",
"organizationType": "Association1901",
"organizationIsUnderColucheLaw": false,
"formName": "name",
"meta": {
"createdAt": "2019-12-15T17:27:02+01:00",
"updatedAt": "2019-12-15T17:27:02+01:00"
},
"isAnonymous": false,
"isAmountHidden": false
},
"payer": {
"email": "john.doe@test.com",
"address": "23 rue du palmier",
"city": "Paris",
"zipCode": "75000",
"country": "FRA",
"company": "Hello Asso",
"dateOfBirth": "1986-07-06T00:00:00+02:00",
"firstName": "John",
"lastName": "Doe"
},
"items": [
{
"shareAmount": 11000,
"shareItemAmount": 10000,
"shareOptionsAmount": 1000,
"id": 12578,
"amount": 30000,
"type": "Membership",
"state": "Processed"
},
{
"shareAmount": 1000,
"shareItemAmount": 1000,
"id": 12579,
"amount": 1000,
"type": "Donation",
"state": "Processed"
}
],
"paymentReceiptUrl": "https://www.helloasso.com/associations/association-exemple/evenements/formulaire-exemple/paiement-attestation/12578",
"id": 12345,
"amount": 5550,
"date": "2024-04-04T23:12:53.6767445+02:00",
"paymentMeans": "Card",
"installmentNumber": 1,
"state": "Authorized",
"meta": {
"createdAt": "2024-04-04T23:12:53.6767445+02:00",
"updatedAt": "2024-04-04T23:12:53.6767445+02:00"
}
},
"eventType": "Payment"
}

0 comments on commit 26cdc2d

Please sign in to comment.