Paypal Express - Hide Shipping Methods and Shipping Costs - paypal

I'm using PayPal Express in my shop and determine the shipping costs after the user comes back to the shop after signing in via PayPal Express.
Right now I'm passing no shipping costs, because I want to hide the entire shipping costs/methods (marked yellow)
How is this possible? My current requests looks like this:
["CALLBACKVERSION"]=>
string(4) "84.0"
["LOCALECODE"]=>
string(5) "de_DE"
["SOLUTIONTYPE"]=>
string(4) "Mark"
["BRANDNAME"]=>
string(8) "Foo"
["CARTBORDERCOLOR"]=>
string(0) ""
["RETURNURL"]=>
string(168) "..."
["CANCELURL"]=>
string(111) "..."
["PAYMENTREQUEST_0_PAYMENTACTION"]=>
string(4) "Sale"
["CALLBACK"]=>
string(158) "..."
["CALLBACKTIMEOUT"]=>
int(6)
["NOSHIPPING"]=>
string(1) "2"
["PAYMENTREQUEST_0_AMT"]=>
string(4) "1.19"
["PAYMENTREQUEST_0_CURRENCYCODE"]=>
string(3) "EUR"
["PAYMENTREQUEST_0_ITEMAMT"]=>
string(4) "1.25"
["PAYMENTREQUEST_0_DESC"]=>
string(50) "..."
["PAYMENTREQUEST_0_CUSTOM"]=>
string(50) "..."
["MAXAMT"]=>
string(5) "32.25"
["L_PAYMENTREQUEST_0_NAME0"]=>
string(12) "Gesamtsumme:"
["L_PAYMENTREQUEST_0_AMT0"]=>
string(4) "1.25"
["L_PAYMENTREQUEST_0_QTY0"]=>
int(1)
This results in an error from PayPal
"Flat-rate shipping options are missing; you must specify flat-rate
shipping options when you specify a callback URL."
But if I pass any shipping costs, it is shown as above. How can I hide them?

Found out that according to documentation, FlatRateShippingOptions - ebl:ShippingOptionsType is required if you are specifying the Callback URL.
When I look at the documentation about ShippingOptionsType here, this looks like something you want to do;
false — PayPal does not display this flat-rate shipping option and its
amount as the default shipping option.
There are three (plus 2) fields you need to add:
1. "L_SHIPPINGOPTIONISDEFAULTn":
If you specify false, you can adjust either or both of these values:
- PAYMENTREQUEST_n_TAXAMT
- PAYMENTREQUEST_n_INSURANCEAMT
2. "L_SHIPPINGOPTIONNAMEn"
3. "L_SHIPPINGOPTIONAMOUNTn"
Hope this can help you!

Related

OData V4 boolean unexpectedly converted to 'No' / 'Yes' strings for ODatamodel V4 binding

From testing it turns out the boolean returned by the OData V4 service was translated to strings 'No' and 'Yes' somewhere between the READ and the binding. I have no idea what can be causing this.
OData loaded by $batch request to load suggestion items:
{
"#odata.context": "$metadata#SkillVocabularyItems",
"value": [
{
"randomId": "622d4068-9928-4446-931a-45b443356dae",
"skill": "MongoDB",
"trending": true
},
{
"randomId": "d9ed304a-c1bc-454c-b4db-970f87ee3943",
"skill": "MongoLab",
"trending": false
}
]
}
XML binding that I expect to work
<SearchField
id="searchField"
busy="{view>/loadingSkillSuggestions}"
placeholder="Search for a skill..."
enableSuggestions="true"
suggest=".onSuggestSkills"
suggestionItems="{/SkillVocabularyItems}"
>
<suggestionItems>
<SuggestionItem
icon="{= ${trending}? 'sap-icon://trend-up' : '' }"
text="{skill}"
description="{trending}"
key="{skill}"
/>
</suggestionItems>
</SearchField>
XML binding that works, showing the value in the model is litterally 'No' or 'Yes'. This 'No' or 'Yes' is also visible in the 'description' of the SuggestionItems.
<SearchField
id="searchField"
busy="{view>/loadingSkillSuggestions}"
placeholder="Search for a skill..."
enableSuggestions="true"
suggest=".onSuggestSkills"
suggestionItems="{/SkillVocabularyItems}"
>
<suggestionItems>
<SuggestionItem
icon="{= ${trending}? 'sap-icon://trend-up' : '' }"
text="{skill}"
description="{trending}"
key="{skill}"
/>
</suggestionItems>
</SearchField>
Found the documentation where this behavior is described.
By default, a property binding delivers a value formatted according to the target type of the control property it applies to...
Source: Type Determination
The solution is to use % for the binding expression instead of $:
The embedded binding ${binding} delivers a value formatted according to the target type of the control property the expression binding applies to, for example, "boolean" in case of <Icon src="sap-icon://message-warning" visible="{= ${status} === 'critical' }">. This can be undesirable or even lead to errors, for example, if OData V4 automatically adds the correct type for the "status" property which is string-like, not boolean. In such cases, use the syntax %{binding} instead.
Source: Expression Binding

Azure Pipelines: Bulk approve of deployments to environments

Is there any way to approve runs via the CLI or the API (or anything else)? I'm looking for a way to bulk approve multiple runs from different pipelines but it's not available in the UI.
Let's say I have 100 pipelines that have a deployment job to a production environment. I would like to approve all awaiting for approval runs.
Currently, I cannot find something like it in the docs of the Azure DevOps REST API or the CLI.
The feature docs:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/environments
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/approvals
The following question is related but I'm looking for any way of solving it but not just via API:
Approve a yaml pipeline deployment in Azure DevOps using REST api
I was just searching for an answer for this regarding getting the approval id that you would need. In fact there is an undocumented API to approve an approval check.
This is as Merlin explain the following
https://dev.azure.com/{org}/{project}/_apis/pipelines/approvals/{approvalId}
The body has to look like this
[{
"approvalId": "{approvalId}",
"status": {approvalStatus},
"comment": ""
}]
where {approvalStatus} is telling the API if you approved or not. You probly have to try, but I had a 4 as a status. I guess there are only 2 possibilities. Either for "approved" or "denied".
The question is now how you get the approval ID? I found it. You get it by using the timeline API of a classic build. The build API documentation says that you get it by the following
https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=5.1
the build timeline you get in the response of the build run, but it has a pattern which is
https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/Timeline?api-version=5.1
Besides a flat array container a parent / child rleationship from stage, phase, job and tasks, you can find within it something like the following:
{
"records": [
{
"previousAttempts": [
],
"id": "95f5837e-769d-5a92-9ecb-0e7edb3ac322",
"parentId": "9e7965a8-d99d-5b8f-b47b-3ee7c58a5b1c",
"type": "Checkpoint",
"name": "Checkpoint",
"startTime": "2020-08-14T13:44:03.05Z",
"finishTime": null,
"currentOperation": null,
"percentComplete": null,
"state": "inProgress",
"result": null,
"resultCode": null,
"changeId": 73,
"lastModified": "0001-01-01T00:00:00",
"workerName": null,
"details": null,
"errorCount": 0,
"warningCount": 0,
"url": null,
"log": null,
"task": null,
"attempt": 1,
"identifier": "Checkpoint"
},
{
"previousAttempts": [
],
"id": "9e7965a8-d99d-5b8f-b47b-3ee7c58a5b1c",
"parentId": null,
"type": "Stage",
"name": "Power Platform Test (orgf92be262)",
"startTime": null,
"finishTime": null,
"currentOperation": null,
"percentComplete": null,
"state": "pending",
"result": null,
"resultCode": null,
"changeId": 1,
"lastModified": "0001-01-01T00:00:00",
"workerName": null,
"order": 2,
"details": null,
"errorCount": 0,
"warningCount": 0,
"url": null,
"log": null,
"task": null,
"attempt": 1,
"identifier": "Import_Test"
},
{
"previousAttempts": [
],
"id": "e54149c5-b5a7-4b82-8468-56ad493224b5",
"parentId": "95f5837e-769d-5a92-9ecb-0e7edb3ac322",
"type": "Checkpoint.Approval",
"name": "Checkpoint.Approval",
"startTime": "2020-08-14T13:44:03.02Z",
"finishTime": null,
"currentOperation": null,
"percentComplete": null,
"state": "inProgress",
"result": null,
"resultCode": null,
"changeId": 72,
"lastModified": "0001-01-01T00:00:00",
"workerName": null,
"details": null,
"errorCount": 0,
"warningCount": 0,
"url": null,
"log": null,
"task": null,
"attempt": 1,
"identifier": "e54149c5-b5a7-4b82-8468-56ad493224b5"
}
],
"lastChangedBy": "00000002-0000-8888-8000-000000000000",
"lastChangedOn": "2020-08-14T13:44:03.057Z",
"id": "86fb4204-9c5e-4e72-bdb1-eefe230480ec",
"changeId": 73,
"url": "https://dev.azure.com/***"
}
below you can see a step that is called "Checkpoint.Approval". The id of that step IS the approval Id you need to approve everything. If you want to know from which stage the approval is, then you can follow up the parentIds until the parentId property is null.
This will then be the stage.
With this you can successfully get the approval id and use it to approve with the said
What jessehouwing's guess is correct. Now multi-stage still be in preview, and the corresponding SDK/API/extension hasn't been expanded and provided to public.
You may think that what about not using API. I have checked the corresponding code from our backend, all of operations to multi-stage approval contain one required parameter: approvalId. I'm sure you have known that this value is unique and different approval map with different approvalId value. This means, no matter which method you want to try with, approvalId is the big trouble. And based on my known, until now, there's no any api/SDK, third tool or extension can achieve this value directly.
In addition, for multi-stage YAML, its release process logic is not same with the release that defined with UI. So, all of public APIs which can work with release(UI), are not suitable with the release of multi-stage.
We have one undisclosed api, can get Approval message of multi-stage:
https://dev.azure.com/{org}/{project}/_apis/pipelines/approvals/{approvalId}
You can try with listing approval without specifying approvalId: https://dev.azure.com/{org}/{project}/_apis/pipelines/approvals. And its response message: Query for approvals failed. A minimum of one query parameter is required.\r\nParameter name: queryParameters. This represents you must tell system the specified approval(the big trouble I mentioned previously).
In fact, for why approvalId is a necessary part, it is caused from our backend code structure. I'd suggest you raise suggestion on developing API/SDK for multi-stage here.
I can confirm that Sebastian's answer worked for me, even in Azure DevOps 2020 on-prem.
After retrieving the approvalId from either methods used above (I was specifically using a service hook for my integration), I used the following API PATCH call:
https://dev.azure.com/{organization}/{project}/_apis/pipelines/approvals/?api-version=6.0-preview
and in the body:
[
{
"approvalId": "{approvalId}",
"status": {status integer}, (4 - approved; 8 - rejected)
"comment": ""
}
]
The call is passed with the application/json Content-Type, but in some situations it did not like that I was using the [] brackets, so you will need to work around that, only then will the call work.
I was even able to integrate this call into my custom connector in MS Power Automate
I added support to the latest version of the AzurePipelinesPS Powershell module to support bulk pipeline approvals.
Code snippet without using the AzurePipelinesPS sessions
$instance = 'https://dev.azure.com'
$collection = 'your_project'
$project = 'your_project'
$apiVersion = '5.1-preview'
$securePat = 'your_personal_access_token' | ConvertTo-SecureString -Force -AsPlainText
Get-APPipelinePendingApprovalList -Instance $instance -Collection $collection -Project $project -PersonalAccessToken $securePat -ApiVersion $apiVersion | Out-GridView -Passthru | % { Update-APPipelineApproval -Instance $instance -Collection $collection -Project $project -PersonalAccessToken $securePat -ApiVersion $apiVersion -ApprovalId $PSitem.approvalId -status 'approved'}
Code snippet with AzurePipelinesPS sessions
$session = 'your_session'
Get-APPipelinePendingApprovalList $session | Out-GridView -Passthru | % { Update-APPipelineApproval $session -ApprovalId $PSitem.approvalId -status 'approved'}
See the AzurePipelinesPS project page for details on secure session handling.
Function Definitions used in the code above
Get-APPipelinePendingApprovalList
Loops through pipeline build runs with the status of 'notStarted' or 'inProgress' in a project. This build lookup supports filters like pipeline definition ids or a source branch name.
For each build it then looks up the timeline record where the approval id, the stage name and the stage identifier are found.
Optionally with the ExpandApproval switch it can expand each approval with details
The object returned from this function contains the following properties, the values have been mocked
pipelineDefinitionName : MyPipeline
pipelineDefinitionId : 100
pipelineRunId : 2001
pipelineUrl : https://dev.azure.com/your_project/_build/results?
sourceBranch : refs/heads/master
stageName : Prod Deployment
stageIdentifier : Prod_Deployment
approvalId : xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx
Out-GridView
Displays data in a Grid View where the results can be filtered, ordered and selected.
%
The percent sign is shorthand for Foreach-Object
Update-APPipelineApproval
Updates the status of an approval to approved or rejected.
Credit
Thanks to Sebastian Schütze for cracking the timeline part!
The az pipelines extension doesn't suport approvals yet, I suppose due to the fact that multi-stage pipelines are still in preview and the old release hub will eventually be replaced by it.
But there is a REST API you can use to list and update approvals. These can be called from PowerShell with relative ease.
Or use the vsteam powershell module and Get-VSTeamApproval and Set-VSTeamApproval.

SoftLayer_Virtual_Guest setTransientWebhook

I'm looking for a sample code using SoftLayer_Virtual_Guest::setTransientWebhook for Transient VSI. Is there a sample code?
Thanks
Behzad
Try with next requests:
Method GET
http://api.softlayer.com/rest/v3.1/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,transientGuestFlag]&objectFilter={"virtualGuests":{"transientGuestFlag":{"operation": 1}}}
Data 1 means true also 0 means false, in this case, we use one with data 1
Choose the VSI id you want to set and use the following request:
Method POST
http://api.softlayer.com/rest/v3.1/SoftLayer_Virtual_Guest/111111/setTransientWebhook
Body
{"parameters":[
"https://test1.com",
"testsupport"]
}
The 111111 data is the VSI that we chose in the previous request.
Reference
https://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest/#transientGuestFlag
https://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/setTransientWebhook/
I hope it helps you
Thanks Daniel, would this be equivalent code in python: request = client['Virtual_Guest'].createObject({
'hostname': hostname,
'domain': domainname,
'startCpus': cpus,
'maxMemory': memory,
'hourlyBillingFlag': 'true',
'datacenter': {'name': 'tor01'},
'operatingSystemReferenceCode': os_code,
# 'localDiskFlag': 'false',
"supplementalCreateObjectOptions": {"flavorKeyName": "C1_1X1X25"},
'transientGuestFlag': 'true',
# 'sshKeys': [{"id":201867}]
"parameters":["https://test1.com","testsupport"].

Extracting Client ID as a custom dimension with audience dimensions through API

I'm looking to get some answers here regarding the matter. There is no formal documentation available, would like some answers to my dilemma. Currently on analytics, I have Client ID setup as a custom dimension, session scope, I'm currently trying to match this Client ID with other dimensions via the Analytics Reporting API v4. (Reason having done so is that because in order for Client ID to be available outside of User Explorer on Analytics, one has to setup a custom dimension for this)
It's come to my attention that when I try to match Client ID, with an Audience Dimension, such as Affinity, nothing comes up. But say I do so with another dimension like PagePath + Affinity, the table exist. So I know that it is possible to pull Audience dimensions with other dimensions and it's possible for me to pull Client ID together with other dimensions. But what I'm trying to understand is why can't I pull Client ID together with Audience dimensions?
Some clarification on the matter would truly be appreciated, thanks.
For example (Can't show everything, but this is the response body of the python script)
In the case that i try to match my custom dimension (Client ID, session scope) with Affinity.
request_report = {
'viewId': VIEW_ID,
'pageSize' : 100000,
'dateRanges': [{'startDate': '2018-12-14',
'endDate': 'today'}],
'metrics': [{'expression': 'ga:users'}
],
'dimensions': [{'name': 'ga:dateHour'},
{'name':'ga:dimension1'},
{'name': 'ga:interestAffinityCategory'}
]
}
response = api_client.reports().batchGet(
body={
'reportRequests': request_report
}).execute()
Output:
ga:dateHour ga:dimension1 ga:interestAffinityCategory ga:users
Changing my dimensions, to pagePath + Affinity
request_report = {
'viewId': VIEW_ID,
'pageSize' : 100000,
'dateRanges': [{'startDate': '2018-12-14',
'endDate': 'today'}],
'metrics': [{'expression': 'ga:users'}
],
'dimensions': [{'name': 'ga:dateHour'},
{'name': 'ga:pagePath'},
{'name': 'ga:interestAffinityCategory'}
]
}
response = api_client.reports().batchGet(
body={
'reportRequests': request_report
}).execute()
Output:
ga:dateHour ga:pagePath ga:interestAffinityCategory ga:users
2018121415 homepage Business Professionals 10
2019011715 join-beta Beauty Mavens 16
2019011715 join-beta Frequently Visits Salons 21
Now say I change my combination to custom dimension + device category
request_report = {
'viewId': VIEW_ID,
'pageSize' : 100000,
'dateRanges': [{'startDate': '2018-12-14',
'endDate': 'today'}],
'metrics': [{'expression': 'ga:users'}
],
'dimensions': [{'name': 'ga:dateHour'},
{'name': 'ga:adContent'},
{'name': 'ga:deviceCategory'}
]
}
response = api_client.reports().batchGet(
body={
'reportRequests': request_report
}).execute()
Output:
ga:dateHour ga:dimension1 ga:adContent ga:deviceCategory ga:users
2018121410 10 ad1 desktop 1
2018121410 111 ad1 mobile 1
2018121410 119 ad4 mobile 1
2018121410 15 ad3 desktop 1
2018121410 157 ad3 mobile 1
In conclusion:
What I'd like to achieve is being able to pair my custom dimensions (Client ID) together with audience dimensions in order to be able to do segmentations. But first things first, if this permutation is not possible, I would like to understand as to why it's not possible? Is this a limitation from the API side? Or is this a policy thing (taking a guess here as I understand that there are identity protection policies)?
The BigQuery integration does not contain demographics/affinitys. The User Interface contains a variety of mechanisms to prevent you from isolating individual users, so in short no.

Rails 4 - Order of has_many, through nested attributes in form

tl,dr: How can I ensure that the order of my has_many, through nested attributes, with an attribute value set in the build, are always assigned the same nested parameters hash key number (0, 1, etc.) and always appear in the form in the same order?
Hopefully I can describe this so it makes sense. I have a small prototype app that simulates a simple bank transfer between two accounts, a source account and a destination account. I have a Transfer class, an Account class and a TransferAccounts class that is the through join for the many_to_many association between Transfer and Account.
Here is the new action in the TransfersController:
def new
#transfer = Transfer.new
#transfer.transfer_accounts.build(account_transfer_role: 'source').build_account
#transfer.transfer_accounts.build(account_transfer_role: 'destination').build_account
bank_selections
account_selections
end
And the strong parameters:
def transfer_params
params.require(:transfer).
permit(:name, :description,
transfer_accounts_attributes:
[:id, :account_id, :account_transfer_role,
account_attributes:
[:id, :bank_id, :name, :description, :user_name,
:password, :routing_number, :account_number
]
])
end
So, the two transfer_accounts associated with a transfer each have an account_transfer_role attribute, with one of them set to source and the other set to destination.
Now, when filling in the form and submitting, the parameters look like the following in console:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxxxxxxxxxxxxxxx==",
"transfer"=>{"name"=>"Test Transfer 2", "description"=>"Second test transfer",
"transfer_accounts_attributes"=>{"0"=>{"account_transfer_role"=>"source", "account_id"=>"1",
"account_attributes"=>{"bank_id"=>"1", "name"=>"George's Checking",
"description"=>"George's personal checking account", "user_name"=>"georgeckg",
"password"=>"[FILTERED]", "account_number"=>"111111111", "routing_number"=>"101010101",
"id"=>"3"}, "id"=>"3"}, "1"=>{"account_transfer_role"=>"destination", "account_id"=>"2",
"account_attributes"=>{"bank_id"=>"2", "name"=>"George's Savings",
"description"=>"George's personal savings account", "user_name"=>"georgesav",
"password"=>"[FILTERED]", "account_number"=>"111101111", "routing_number"=>"100100100",
"id"=>"4"}, "id"=>"4"}}}, "commit"=>"Update Transfer", "id"=>"2"}
As you can see, each transfer_account in the the transfer_account_attributes hash has an id key, either a 0 or a 1 (e.g. ..."0"=>{"account_transfer_role"=>"source"...). Now, I have been working under the assumption (which I thought might come back to bite me, and it has) that because of the order they are built in the new action, that the source transfer_account would always have an id key of 0 and the destination transfer_account would always have an id key of 1, which led me to use these id keys elsewhere in the controller as though 0 represented source and 1 represented destination.
And all seemed to be working fine until I was trying different permutations of creating new or using existing accounts, creating new or editing existing transfers when suddenly the form appears with destination listed first and source second, which hadn't occurred before, causing the entries to now have destination associated with 0 and source associated with 1, breaking the code in the controller referred to above.
To make it clearer, here is the form:
#transfer_form
= simple_form_for #transfer do |t|
.form-inputs
= t.input :name, label: 'Transfer Name'
= t.input :description, required: false, label: 'Transfer Description'
= t.simple_fields_for :transfer_accounts do |ta|
- role = ta.object.account_transfer_role.titleize
= ta.input :account_transfer_role, as: :hidden
= ta.input :account_id, collection: #valid_accounts,
include_blank: 'Select account...',
label: "#{ role } Account",
error: 'Account selection is required.'
.account_fields{id: "#{ role.downcase }_account_fields"}
= ta.simple_fields_for :account do |a|
= a.input :bank_id, collection: #valid_banks,
include_blank: 'Select bank...',
label: "#{ role } Bank",
error: 'Bank selection is required.',
class: "#{ role.downcase }_account_input_field"
= a.input :name, label: "#{ role } Account Name",
class: "#{ role.downcase }_account_input_field"
= a.input :description, required: false,
label: "#{ role } Account Description",
class: "#{ role.downcase }_account_input_field"
= a.input :user_name, label: "#{ role } Account User Name",
class: "#{ role.downcase }_account_input_field"
= a.input :password, label: "#{ role } Account Password",
class: "#{ role.downcase }_account_input_field"
= a.input :account_number, label: "#{ role } Account Number",
class: "#{ role.downcase }_account_input_field"
= a.input :routing_number, label: "#{ role } Account Routing Number",
class: "#{ role.downcase }_account_input_field"
= t.submit
How do I ensure that source is always first and, thus, always associated with the id key 0 and destination is always second, always associated with the id key 1?
The answer appears to be as simple as changing the :transfer_accounts association line in my Transfer model from this:
has_many :transfer_accounts, inverse_of: :transfer
to this:
has_many :transfer_accounts, -> { order('account_transfer_role DESC') }, inverse_of: :transfer
If anyone believes it is not doing what I think it is doing, please let me know, because, at the moment it appears to be resolving my issue.