10 Commits
Author SHA1 Message Date
pixel-workflows[bot] c94788fdb8 chore: update dependabot configuration 2026-07-27 23:27:56 +00:00
pixel-workflows[bot] 3a5c51d3d0 chore: sync files from wearepixel/pixel-workflows - synced local 'pint.json' with remote 'files/pint.json' 2026-07-27 08:21:02 +00:00
pixel-workflows[bot] f7d07f45e5 chore: sync files from wearepixel/pixel-workflows - created local '.gitattributes' from remote 'files/.gitattributes' 2026-07-27 08:20:59 +00:00
pixel-workflows[bot] b4a5d00439 chore: sync files from wearepixel/pixel-workflows - synced local '.editorconfig' with remote 'files/.editorconfig' 2026-07-27 08:20:56 +00:00
pixel-workflows[bot] 524a09d545 chore: sync files from wearepixel/pixel-workflows - created local '.github/workflows/dependabot-slack-alert.yml' from remote 'files/.github/workflows/dependabot-slack-alert.yml' 2026-07-27 08:20:53 +00:00
pixel-workflows[bot] c75ab43346 chore: sync files from wearepixel/pixel-workflows - created local '.github/workflows/dependabot-auto-merge.yml' from remote 'files/.github/workflows/dependabot-auto-merge.yml' 2026-07-27 08:20:50 +00:00
Joel Male 32266f6dd5 fix: revert JSON serialization workaround, upgrade SDK to 6.3.1 instead
v2.0.1's useJson() workaround was wrong: the JSON request serializer
silently drops nested single-object fields (e.g. CustomerRef, which
QuickBooks requires), and the JSON response deserializer never returns
a typed entity, so $result->Id is always null downstream. That breaks
every dsCall() site, worse than the bug it was meant to fix.

The actual root cause was that quickbooks/v3-php-sdk 5.4.7 predates
QuickBooks Online's new invoice AllowOnlinePayPalPayment field, so its
XML deserializer throws on responses that include it. SDK 6.3.1
declares the field, so upgrading resolves the original error while
keeping the fully-supported XML path (and closes out the SDK bump
Dependabot already had queued in #3).

Verified: deserializing a response containing AllowOnlinePayPalPayment
throws RuntimeException on 5.4.7 and returns a correctly typed
IPPInvoice (with Id populated) on 6.3.1.
2026-07-27 07:15:59 +03:00
Joel Male 9002e0ebca fix: switch DataService to JSON serialization to survive QuickBooks schema drift
The SDK's XML deserializer reflects on declared properties of its Data
classes and throws a RuntimeException when QuickBooks returns a field
the installed SDK version doesn't define yet (e.g. the new invoice
AllowOnlinePayPalPayment field), breaking every invoice create/update.
The JSON path builds instances from the class's own known properties
and silently ignores unrecognised response fields instead, so it
tolerates QuickBooks adding fields ahead of the SDK.
2026-07-27 07:03:21 +03:00
pixel-workflows[bot] 473103c243 chore: update dependabot configuration 2026-05-27 06:18:22 +00:00
Joel Male f59295773d Create SECURITY.md 2026-05-27 14:48:52 +10:00
8 changed files with 288 additions and 62 deletions
+6 -4
View File
@@ -3,14 +3,16 @@ root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.yml]
indent_style = space
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4
+11
View File
@@ -0,0 +1,11 @@
* text=auto eol=lf
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore
+38
View File
@@ -0,0 +1,38 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
groups:
actions:
applies-to: version-updates
patterns: ["*"]
commit-message:
prefix: "chore"
include: "scope"
labels:
- "dependencies"
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
day: "tuesday"
open-pull-requests-limit: 10
groups:
php-minor-patch:
applies-to: version-updates
update-types:
- "minor"
- "patch"
php-security:
applies-to: security-updates
patterns: ["*"]
commit-message:
prefix: "chore"
include: "scope"
labels:
- "dependencies"
@@ -0,0 +1,59 @@
name: Dependabot Auto-merge
on:
workflow_run:
workflows: ["Tests"]
types: [completed]
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
runs-on: ubuntu-latest
if: |
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.actor.login == 'dependabot[bot]'
steps:
- name: Find PR and check update type
id: check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
run: |
PR_DATA=$(gh pr list --repo "${{ github.repository }}" --head "$HEAD_BRANCH" --json number,title,url,author --jq '.[0]')
PR_URL=$(echo "$PR_DATA" | jq -r '.url')
PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
if [ "$PR_AUTHOR" != "app/dependabot" ]; then
echo "is_safe=false" >> $GITHUB_OUTPUT
echo "Not a Dependabot PR, skipping."
exit 0
fi
# Parse major version numbers from title: "bump X from A[.B.C] to D[.E.F]"
# Works for both "from 4.0.0 to 4.1.0" and "from 4 to 6" (GitHub Actions)
FROM_MAJOR=$(echo "$PR_TITLE" | grep -oP 'from \K[0-9]+')
TO_MAJOR=$(echo "$PR_TITLE" | grep -oP 'to \K[0-9]+')
echo "PR: $PR_TITLE (major: $FROM_MAJOR -> $TO_MAJOR)"
if [ "$FROM_MAJOR" = "$TO_MAJOR" ]; then
echo "is_safe=true" >> $GITHUB_OUTPUT
else
echo "is_safe=false" >> $GITHUB_OUTPUT
echo "Major version bump, skipping auto-merge."
fi
- name: Merge minor and patch updates
if: steps.check.outputs.is_safe == 'true'
run: gh pr merge --merge "${{ steps.check.outputs.pr_url }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,98 @@
name: Dependabot Slack Alert
on:
pull_request_target:
types: [opened]
jobs:
notify:
name: Notify Slack of major update
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Check if major version bump
id: check
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
from_major=$(echo "$PR_TITLE" | grep -oP 'from \K[0-9]+' | head -1)
to_major=$(echo "$PR_TITLE" | grep -oP 'to \K[0-9]+' | head -1)
if [ -n "$from_major" ] && [ -n "$to_major" ] && [ "$from_major" != "$to_major" ]; then
echo "is_major=true" >> $GITHUB_OUTPUT
echo "Major bump detected: $from_major -> $to_major"
else
echo "is_major=false" >> $GITHUB_OUTPUT
echo "Minor/patch bump, skipping"
fi
- name: Send Slack alert
if: steps.check.outputs.is_major == 'true'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
run: |
if [ -z "$SLACK_WEBHOOK_URL" ]; then
echo "SLACK_WEBHOOK_URL not configured for this repo, skipping"
exit 0
fi
payload=$(jq -n \
--arg repo "$REPO" \
--arg title "$PR_TITLE" \
--arg url "$PR_URL" \
--arg pr "#$PR_NUMBER" \
'{
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: ":dependabot: *Major dependency update requires review*"
}
},
{
type: "section",
fields: [
{type: "mrkdwn", text: ("*Repository*\n`" + $repo + "`")},
{type: "mrkdwn", text: ("*Pull Request*\n<" + $url + "|" + $pr + ">") }
]
},
{
type: "section",
text: {
type: "mrkdwn",
text: $title
}
},
{
type: "context",
elements: [
{
type: "mrkdwn",
text: "Major version bumps are not auto-merged as they may contain breaking changes."
}
]
},
{
type: "actions",
elements: [
{
type: "button",
text: {type: "plain_text", text: "Review PR"},
url: $url,
style: "primary"
}
]
}
]
}')
curl -s -o /dev/null -w "%{http_code}" -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-type: application/json" \
--data "$payload" | grep -q "^200$" \
&& echo "Slack notification sent" \
|| echo "Slack notification failed"
+11
View File
@@ -0,0 +1,11 @@
# Security Policy
**PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, [SEE BELOW](#reporting-a-vulnerability).**
## Reporting a Vulnerability
If you discover a security vulnerability, please report it privately using the below channel:
**GitHub Private Vulnerability Reporting** — go to the repository's **Security** tab and click **"Report a vulnerability"**. This creates a private advisory visible only to maintainers and provides a structured workflow for triage, fix coordination, and CVE assignment.
All security vulnerabilities will be promptly addressed.
+57 -57
View File
@@ -1,61 +1,61 @@
{
"name": "wearepixel/laravel-quickbooks",
"version": "2.0.0",
"description": "Laravel Client for QuickBooks.",
"keywords": [
"quickbooks",
"client",
"laravel",
"wearepixel"
],
"license": "MIT",
"authors": [
{
"name": "Pixel",
"email": "hello@wearepixel.com.au"
}
],
"require": {
"php": "^8.3",
"illuminate/database": "^10.0|^11.0|^12.0",
"illuminate/http": "^10.0|^11.0|^12.0",
"illuminate/routing": "^10.0|^11.0|^12.0",
"illuminate/support": "^10.0|^11.0|^12.0",
"nesbot/carbon": "^2.62.1|^3.0",
"quickbooks/v3-php-sdk": "^5.4.6"
},
"require-dev": {
"laravel/pint": "^1.2",
"mockery/mockery": "^1.6",
"pestphp/pest": "^3.0",
"psy/psysh": "^0.12"
},
"autoload": {
"psr-4": {
"Wearepixel\\QuickBooks\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Wearepixel\\QuickBooks\\": "tests/"
"name": "wearepixel/laravel-quickbooks",
"version": "2.0.2",
"description": "Laravel Client for QuickBooks.",
"keywords": [
"quickbooks",
"client",
"laravel",
"wearepixel"
],
"license": "MIT",
"authors": [
{
"name": "Pixel",
"email": "hello@wearepixel.com.au"
}
],
"require": {
"php": "^8.3",
"illuminate/database": "^10.0|^11.0|^12.0",
"illuminate/http": "^10.0|^11.0|^12.0",
"illuminate/routing": "^10.0|^11.0|^12.0",
"illuminate/support": "^10.0|^11.0|^12.0",
"nesbot/carbon": "^2.62.1|^3.0",
"quickbooks/v3-php-sdk": "^6.3.1"
},
"files": [
"tests/Overrides.php"
]
},
"extra": {
"laravel": {
"providers": [
"Wearepixel\\QuickBooks\\Providers\\ServiceProvider",
"Wearepixel\\QuickBooks\\Providers\\ClientServiceProvider"
]
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
"require-dev": {
"laravel/pint": "^1.2",
"mockery/mockery": "^1.6",
"pestphp/pest": "^3.0",
"psy/psysh": "^0.12"
},
"sort-packages": true
},
"prefer-stable": true
"autoload": {
"psr-4": {
"Wearepixel\\QuickBooks\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Wearepixel\\QuickBooks\\": "tests/"
},
"files": [
"tests/Overrides.php"
]
},
"extra": {
"laravel": {
"providers": [
"Wearepixel\\QuickBooks\\Providers\\ServiceProvider",
"Wearepixel\\QuickBooks\\Providers\\ClientServiceProvider"
]
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
},
"sort-packages": true
},
"prefer-stable": true
}
+8 -1
View File
@@ -1,6 +1,13 @@
{
"preset": "laravel",
"rules": {
"no_superfluous_phpdoc_tags": true
"concat_space": {
"spacing": "one"
},
"class_attributes_separation": false,
"ordered_imports": {
"sort_algorithm": "length"
},
"not_operator_with_space": false
}
}