ODATA ASP .net core $Filter with Any or All - filter

We are building an API to expose our account data for entities using ODATA REST API.
One of our downstream system wants to consume our API wants to filter data for all Internal Accounts only.
The Query used is $Filter=accounts/all(account: account/Type eq 'Internal')
They get all the Entities with accounts that have 'Internal' but few missing entities. One such missing entity in output payload is "EntityId": 140630.
The only difference between this entity '140630' and other entities that make up to the payload is that, has accounts that belong to both types 'Internal and External'.
But the expectation is that downstream wants all entities that have accounts with type 'Internal' invariably whether the entity has only Internal accounts or both (Internal and External).
Based on our initial analysis, ODATA 'All' filter considers entities that have only Account/Type that has 'Internal' and skips entities with accounts that have both 'Internal' and 'External'.
With 'Any' Filter, entities that have account type 'Internal' + entities that have account type 'Internal' and 'External' are fetched. In this case we see the payload having Entity 140630 with accounts both Internal and External. But as per requirement, the downstream system should not be exposed with 'External' accounts.
Need support to write a fitting ODATA Filter that brings Entities that contains internal accounts. Whether they have only internal accounts or have both internal and External accounts.
From the sample payload provided below
the filtered output should bring entities
"EntityId": 140278, and accounts (Only have internal accounts)
"EntityId": 440365, and accounts (Only have internal accounts)
"EntityId": 140630, and accounts "Id": 228643,"Id": 228647, (Only internal accounts from the list of accounts they have)
Any directions to achieve the above requirement will be much appreciated.
The json payload with out any filter looks like
{
"#odata.context": "https://abc.myteamtest.webdomain.com/TAcctService/API/$metadata#TAccount(Accounts(CIS(),accountRel()))",
"value": [
{
"EntityId": 140278,
"Accounts": [
{
"Id": 229016,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "18951",
"ShortName": "MyBank ABC 124543",
"FullName": "MyBank ABC (OU 124543)",
"TradingBusiness": "ASL",
"Status": "Active",
"accrualCode": "ACC",
"CreatedDt": "2017-11-18T04:29:31.552+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": "admin",
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 229016,
"id": "69776",
"description": "MyBank HOLDINGS INC.",
"CorpCode": "NY001",
"TradingLocation": "YORK SITE",
"OrgunitId": "124543",
"OrgunitDescription": "ABC - FUNDING",
"BusinessUnit": "OTHER",
"Location": "USA",
"ProfitCenter": "124543",
"CustomerGroup": "07956",
"CISLegalEntityId": "07956",
"CISLegalEntityName": "MyBank HOLDINGS INC."
},
"accountRel": {
"TradingCodeAttributesID": 229016,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
}
]
},
{
"EntityId": 440365,
"Accounts": [
{
"Id": 228919,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "21700",
"ShortName": "MyBank 69002",
"FullName": "MyBank Limited (69002)",
"TradingBusiness": "ASL",
"Status": "Active",
"accrualCode": "MTM",
"CreatedDt": "2017-11-18T04:29:33.228+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": "admin",
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 228919,
"id": "69002",
"description": "MyBank LIMITED",
"CorpCode": "WGINT",
"TradingLocation": "UnKnown",
"OrgunitId": "69002",
"OrgunitDescription": "MyBank LIMITED",
"BusinessUnit": "MANAGED",
"Location": "WES",
"ProfitCenter": "69002",
"CustomerGroup": "69002",
"CISLegalEntityId": "69002",
"CISLegalEntityName": "MyBank LIMITED"
},
"accountRel": {
"TradingCodeAttributesID": 228919,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
}
]
},
{
"EntityId": 140630,
"Accounts": [
{
"Id": 219926,
"Type": "External",
"TradingSourceSystem": "MSS",
"TradingCode": "MARINE",
"ShortName": null,
"FullName": "My Bank of Testing",
"TradingBusiness": null,
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2021-01-26T19:24:03.327+05:30",
"UpdatedDt": "2021-01-26T19:19:21+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": null,
"Boadescription": null,
"CorpCode": null,
"TradingLocation": null,
"OrgunitId": null,
"OrgunitDescription": null,
"BusinessUnit": null,
"Location": null,
"ProfitCenter": null,
"CustomerGroup": null,
"CISLegalEntityId": null,
"CISLegalEntityName": null
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
},
{
"Id": 219927,
"Type": "External",
"TradingSourceSystem": "MSS",
"TradingCode": "PRESET",
"ShortName": null,
"FullName": "My Bank of Testing",
"TradingBusiness": null,
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2021-02-23T15:50:46.013+05:30",
"UpdatedDt": "2021-02-23T15:50:45+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": null,
"Boadescription": null,
"CorpCode": null,
"TradingLocation": null,
"OrgunitId": null,
"OrgunitDescription": null,
"BusinessUnit": null,
"Location": null,
"ProfitCenter": null,
"CustomerGroup": null,
"CISLegalEntityId": null,
"CISLegalEntityName": null
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
},
{
"Id": 228643,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "24633",
"ShortName": "AB124 94189",
"FullName": "AB124 CRT",
"TradingBusiness": "MSL",
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2017-11-18T04:29:34.409+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": "09902",
"Boadescription": "OFFICE",
"CorpCode": "ABCC1",
"TradingLocation": "York",
"OrgunitId": "94189",
"OrgunitDescription": "MAP",
"BusinessUnit": "CIO",
"Location": "PAN",
"ProfitCenter": "94189",
"CustomerGroup": "09902",
"CISLegalEntityId": "29997",
"CISLegalEntityName": "My PARENT BANK"
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
},
{
"Id": 228647,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "7574",
"ShortName": "ABC1234 COLL13122",
"FullName": "ABC1234 Collateral Pool",
"TradingBusiness": "MSL",
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2017-11-18T04:29:35.234+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": "09602",
"Boadescription": "P&T",
"CorpCode": "ABC12342",
"TradingLocation": "YORK",
"OrgunitId": "13122",
"OrgunitDescription": "FIC",
"BusinessUnit": "MARKETS",
"Location": "PAN",
"ProfitCenter": "13122",
"CustomerGroup": "09602",
"CISLegalEntityId": "29997",
"CISLegalEntityName": "ABC1234 PARENT BANK"
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
}
]
}
]
}

I'm assuming that you're using EntityFramework in this scenario. If so, I suggest you try this:
public IQueryable<Entity> Get()
{
return _databaseContext.Entities
.Include(entity => entity.Accounts.Where(account => account.Type = "Internal"))
.AsNoTracking();
}```

Related

Error deploying config to Solana network. Error: non-base58 character

I'm testing how Metaplex's Candy Machine works and I'm having the tittle error while uploading using the CMv2-cli.
My config file is the following:
{
"price": 0,
"number": 10,
"gatekeeper": null,
"solTreasuryAccount": "<8TBP4QrwkbDEmmYbA1EJum7HN8S2c1QYvEgTPdfb35Lh>",
"splTokenAccount": null,
"splToken": null,
"goLiveDate": "27 May 2022 09:20:00 UTC",
"endSettings": null,
"whitelistMintSettings": null,
"hiddenSettings": null,
"storage": "arweave-sol",
"ipfsInfuraProjectId": null,
"ipfsInfuraSecret": null,
"nftStorageKey": null,
"awsS3Bucket": null,
"noRetainAuthority": false,
"noMutable": false
}
One of my assets file is the following:
{
"name": "Test #0001",
"symbol": "NB",
"description": "Collection of 10 numbers on the Solana blockchain.",
"seller_fee_basis_points": 500,
"image": "0.png",
"attributes": [
{"trait_type": "Layer-1", "value": "0"},
{"trait_type": "Layer-2", "value": "0"},
{"trait_type": "Layer-3", "value": "0"},
{"trait_type": "Layer-4", "value": "1"}
],
"properties": {
"creators": [{"address": "8TBP4QrwkbDEmmYbA1EJum7HN8S2c1QYvEgTPdfb35Lh ", "share": 100}],
"files": [{"uri": "0.png", "type": "image/png"}]
},
"collection": {"name": "numbers", "family": "numbers"}
}
You have 2 big errors in both files (config and the metadata).
For the config file you should not use the < > symbols, so your config file should look like this:
{
"price": 0,
"number": 10,
"gatekeeper": null,
"solTreasuryAccount": "8TBP4QrwkbDEmmYbA1EJum7HN8S2c1QYvEgTPdfb35Lh",
"splTokenAccount": null,
"splToken": null,
"goLiveDate": "27 May 2022 09:20:00 UTC",
"endSettings": null,
"whitelistMintSettings": null,
"hiddenSettings": null,
"storage": "arweave-sol",
"ipfsInfuraProjectId": null,
"ipfsInfuraSecret": null,
"nftStorageKey": null,
"awsS3Bucket": null,
"noRetainAuthority": false,
"noMutable": false
}
For the asset file you have an extra space at the end of the creators array, so you should remove that extra space from this file and I assume from the rest of ur assets too. Should look like this:
{
"name": "Test #0001",
"symbol": "NB",
"description": "Collection of 10 numbers on the Solana blockchain.",
"seller_fee_basis_points": 500,
"image": "0.png",
"attributes": [
{"trait_type": "Layer-1", "value": "0"},
{"trait_type": "Layer-2", "value": "0"},
{"trait_type": "Layer-3", "value": "0"},
{"trait_type": "Layer-4", "value": "1"}
],
"properties": {
"creators": [{"address": "8TBP4QrwkbDEmmYbA1EJum7HN8S2c1QYvEgTPdfb35Lh", "share": 100}],
"files": [{"uri": "0.png", "type": "image/png"}]
},
"collection": {"name": "numbers", "family": "numbers"}
}

How to Users of a specific Room and filter these users with specific spatie tag?

I have a User model that have spatie tags (developer and consultant).
I have a Room model that have many to many relation with User.
I want to return users of a specific room with tag of "consultant".
Can you please help me to do that?
I can find my specific room by id and also I can use relation to get its users but I dont know how to filter them by tag.
I hope you understand my point.
this is what I tried so far but didnt worked!
$room->users->withAnyTags('consultant');
here is my relation:
public function users()
{
return $this->belongsToMany(User::class, 'skyroom_room_user', 'skyroom_room_id', 'user_id')->with('tags');
}
if I run this:
$room->users;
it will return this:
{
"id": "2c8fdf5a-fe94-4216-a3dc-8a49e76c6e34",
"first_name": null,
"last_name": null,
"email": null,
"slug": null,
"username": "+989353785968",
"gender": "male",
"birthday": null,
"national_code": null,
"sheba": null,
"country": null,
"city": null,
"bio": null,
"long_bio": null,
"education": null,
"language": null,
"type": "trainee",
"avatar": null,
"verified_at": null,
"certified_at": null,
"referred_by": null,
"referred_at": null,
"skyroom_user_id": 9379122,
"skyroom_username": "09353785968",
"skyroom_nickname": "مصطفی طاهری",
"skyroom_access": 1,
"created_at": "2021-04-08T13:22:42.000000Z",
"updated_at": "2021-04-08T13:22:42.000000Z",
"deleted_at": null,
"tags": []
},
{
"id": "33b1a31d-1aae-4c38-8c07-0793de5a4216",
"first_name": "حامد",
"last_name": "پوسانه",
"email": "h.pousaneh#gmail.com",
"slug": "hamed",
"username": "+989127426900",
"gender": "male",
"birthday": "1990-05-28 19:37:12",
"national_code": null,
"sheba": null,
"country": "Iran",
"city": "Tehran",
"bio": "مدیریت کسب و کار",
"long_bio": "مدیریت کسب و کار از دانشگاه صنعتی امیرکبیر",
"education": "کارشناسی ارشد",
"language": "فارسی، آذری و انگلیسی",
"type": "trainer",
"avatar": null,
"verified_at": null,
"certified_at": null,
"referred_by": "a9ca25bd-18fb-4271-8155-0a75d9dc31d9",
"referred_at": null,
"skyroom_user_id": 8025480,
"skyroom_username": "09127426900",
"skyroom_nickname": "حامد پوسانه",
"skyroom_access": 3,
"created_at": "2021-04-08T13:06:24.000000Z",
"updated_at": "2021-04-08T15:07:13.000000Z",
"deleted_at": null,
"tags": [
{
"id": "71de78b1-15ad-410d-9778-50cb9b3bd4ca",
"name": {
"en": "consultant"
},
"slug": {
"en": "consultant"
},
"type": "user-system-tag",
"order_column": 3,
"created_at": "2021-04-08T13:06:24.000000Z",
"updated_at": "2021-04-08T13:06:24.000000Z",
"pivot": {
"taggable_id": "33b1a31d-1aae-4c38-8c07-0793de5a4216",
"tag_id": "71de78b1-15ad-410d-9778-50cb9b3bd4ca",
"taggable_type": "App\\Models\\User"
}
},
Assuming you have created your relationships correctly, the syntax for retrieving tagged models would be:
$room->users()->withAnyTags('consultant')->get()
If you wanted to search for multiple tags, you would provide an array to withAnyTags:
$room->users()->withAnyTags(['consultant', 'developer'])->get()

How to change the response in API

I want to change my response in an API. I get the user object in response but i want there the object of join like that here is the code of my Activity Profile Controller in which I get user object.
Currently i get this response.
"user": {
"id": 1,
"facebook_id": null,
"name": "umar",
"surname": "javed",
"email": "uj1#gmail.com",
"username": null,
"date_of_birth": "1993-01-18",
"profile_picture": null,
"occupation": null,
"gender": null,
"city": "lahore",
"country": null,
"course": null,
"university": null,
"discription": null,
"visible_on_feeds": 1,
"visible_on_guestlists": 1,
"created_at": "2018-05-02 10:35:03",
"updated_at": "2019-01-15 14:32:54"
}
public function joinActivity(Activity $activity)
{
$authUser = JWTAuth::parseToken()->toUser();
$userAge = Carbon::parse($authUser->date_of_birth)->age;
if($activity->age_from <= $userAge && $activity->age_to >= $userAge)
{
$authUser->joinActivity($activity, $authUser);
if ($activity->user_id != $authUser->id) {
$user = User::where('id', $activity->user_id)->first();
$user->notify(new JoinedTheActivity($authUser, $activity));
}
$userFriendIds = $authUser->friendslist()->pluck('id')->toArray();
$joinedIds = $activity->joins()->pluck('user_id')->toArray();
$joinedUsers = User::whereIn('id', $joinedIds)->whereIn('id', $userFriendIds)
->where('id', '!=', $authUser->id)->get();
foreach ($joinedUsers as $joinedUser) {
$joinedUser->notify(new FriendJoinedSameActivity($authUser, $activity));
}
return response()->json(['user'=> $authUser], 200);
} else {
return response()->json(['message'=> 'Your are not under the age limit of this Activity']);
}
}
And Here is the code of my ActivityInterest trait:
public function joinActivity(Activity $activity, User $user)
{
if ( $this->isJoiningActivity($activity, $user))
{
$activity->interests()->update(['status'=> Status::JOINED]);
} else {
$joining = $activity->interests()->create([
'user_id' => $user->id,
'activity_id' => $activity->id,
'status' => Status::JOINED,
]);
return $joining->save();
}
}
But I want this response How i can do that Please help Me. Thanks in advance.
"joins": [
{
"id": 71,
"user_id": 1,
"activity_id": 7,
"status": 1,
"created_at": "2018-12-21 07:05:30",
"updated_at": "2018-12-21 07:05:30",
"user": {
"id": 1,
"facebook_id": null,
"name": "umar",
"surname": "javed",
"email": "uj1#gmail.com",
"username": null,
"date_of_birth": "1993-01-18",
"profile_picture": null,
"occupation": null,
"gender": null,
"city": "lahore",
"country": null,
"course": null,
"university": null,
"discription": null,
"visible_on_feeds": 1,
"visible_on_guestlists": 1,
"created_at": "2018-05-02 10:35:03",
"updated_at": "2019-01-15 14:32:54"
},
"activity": {
"id": 7,
"activity_type": "event",
"user_id": 1,
"category_id": 2,
"subcategory_id": 3,
"activity_privacy": "open",
"activity_privacy_visible": 1,
"activity_datetime_from": "2018-07-28 13:35:00",
"activity_datetime_to": "2018-12-12 04:10:12",
"activity_address": "lahore",
"company_id": 3,
"latitude": null,
"longitude": null,
"age_from": 16,
"age_to": 30,
"people_limit": "4",
"activity_picture": null,
"activity_title": "party",
"activity_description": "party bla bla",
"created_at": "2018-05-03 10:49:48",
"updated_at": "2018-09-29 07:57:10",
"user": {
"id": 1,
"facebook_id": null,
"name": "umar",
"surname": "javed",
"email": "uj1#gmail.com",
"username": null,
"date_of_birth": "1993-01-18",
"profile_picture": null,
"occupation": null,
"gender": null,
"city": "lahore",
"country": null,
"course": null,
"university": null,
"discription": null,
"visible_on_feeds": 1,
"visible_on_guestlists": 1,
"created_at": "2018-05-02 10:35:03",
"updated_at": "2019-01-15 14:32:54"
},
"subcategory": {
"id": 3,
"category_id": 2,
"subcategory_name": "party",
"subcategory_picture": "dds",
"created_at": null,
"updated_at": null,
"category": {
"id": 2,
"category_name": "nightlife",
"category_picture": "knk",
"category_color": "#992233",
"created_at": null,
"updated_at": "2018-08-09 11:21:23"
}
}
}
}
]
When you need to change a response in your api, you can create a resource. this is the correct way, and will help you returning the information the way you need it.
In example, php artisan make:resource UserCollection
More info here:
https://laravel.com/docs/5.7/eloquent-resources

How can I get the Bot to list/get the participants or members on a group conversation?

I have created a skypeBot that can be added to a group conversation. Is there a way on how the bot can get the list of participants on from the conversation?
There are at least 2 ways to get the participants of a group conversation with a bot in Skype, but you will get their IDs only:
Case 1: By checking the ConversationUpdate message that is raised when creating the conversation.
Sample (made with one of my bots):
{
"type": "conversationUpdate",
"id": "f:6c9b7aa2",
"timestamp": "2017-06-30T11:40:09.3Z",
"localTimestamp": null,
"serviceUrl": "https://smba.trafficmanager.net/apis/",
"channelId": "skype",
"from": {
"id": "29:1AE5BB....",
"name": null
},
"conversation": {
"isGroup": true,
"id": "19:fd3d....#thread.skype",
"name": null
},
"recipient": {
"id": "28:myBotAppId",
"name": "myBotName"
},
"textFormat": null,
"attachmentLayout": null,
"membersAdded": [{
"id": "29:1AE5BB...",
"name": null
}, {
"id": "29:1DwlGVz...",
"name": null
}, {
"id": "28:myBotAppId",
"name": null
}],
"membersRemoved": [],
"topicName": null,
"historyDisclosed": null,
"locale": null,
"text": null,
"speak": null,
"inputHint": null,
"summary": null,
"suggestedActions": null,
"attachments": [],
"entities": [],
"channelData": null,
"action": null,
"replyToId": null,
"value": null,
"name": null,
"relatesTo": null,
"code": null
}
Here you have 2 users that are in the group conversation in the membersAdded block: 29:1AE5BB.... and 29:1DwlGVz.... The last ID is the bot ID
Case 2: by requesting the API.
You can do a GET request to https://smba.trafficmanager.net/apis/v3/conversations/yourConversationId/members and you will get the same 2 IDs.
See also more details here: https://github.com/Microsoft/BotBuilder-Samples/tree/master/Node/core-GetConversationMembers
So from C# code you can do the following:
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
var members = connector.Conversations.GetConversationMembersWithHttpMessagesAsync(activity.Conversation.Id).Result.Body;
For c# you can try this in the messageController
ConnectorClient connector = new ConnectorClient(new System.Uri(activity.ServiceUrl));
var members = connector.Conversations.GetConversationMembersWithHttpMessagesAsync(activity.Conversation.Id).Result.Body;

Laravel Cashier: Resume a single payment

after a successful payment I store the stripe id on a mysql table. With that id I would like to retrieve all the details stored in the stripe database.
So is it possible to resume a single payment by the stripe id?
Thanks
Here is the documentation you need to use: https://stripe.com/docs/api/php#retrieve_customer
Use the "customer retrieve" Stripe API call to retrieve details about the customer's purchase:
Stripe::setApiKey(Config::get('your_stripe_secret_key_here'));
$customer_object = Customer::retrieve(customers_stripe_id);
This will return the following JSON:
Stripe\Customer JSON: {
"id": "cus_7KJZQ8Z6jfSSMl",
"object": "customer",
"account_balance": 0,
"created": 1447172728,
"currency": "usd",
"default_source": "card_175evz2eZvKYlo2CKoS2WEDk",
"delinquent": false,
"description": "Bingo|www|0c1234567890",
"discount": null,
"email": null,
"livemode": false,
"metadata": {
},
"shipping": null,
"sources": {
"object": "list",
"data": [
{
"id": "card_175evz2eZvKYlo2CKoS2WEDk",
"object": "card",
"address_city": null,
"address_country": null,
"address_line1": null,
"address_line1_check": null,
"address_line2": null,
"address_state": null,
"address_zip": null,
"address_zip_check": null,
"brand": "Visa",
"country": "US",
"customer": "cus_7KJZQ8Z6jfSSMl",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 5,
"exp_year": 2016,
"funding": "credit",
"last4": "4242",
"metadata": {
},
"name": null,
"tokenization_method": null
}
],
"has_more": false,
"total_count": 1,
"url": "/v1/customers/cus_7KJZQ8Z6jfSSMl/sources"
},
"subscriptions": {
"object": "list",
"data": [
],
"has_more": false,
"total_count": 0,
"url": "/v1/customers/cus_7KJZQ8Z6jfSSMl/subscriptions"
}
}
Here is Stripe's version of the API call:
\Stripe\Stripe::setApiKey("your_secret_key");
\Stripe\Customer::retrieve("the_customers_id");
Make sure to import the \Stripe classes by adding this at the top of your Model or Controller:
use Stripe\Customer;
use Stripe\Stripe;
if you want to use "Stripe" instead of \Stripe\Stripe and \Stripe\Customer prefixes)

Resources