CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-github-binarywang--weixin-java-miniapp

Comprehensive Java SDK for WeChat MiniApp development with complete platform integration

Pending
Overview
Eval results
Files

qr-codes.mddocs/

QR Code Generation

Generate various types of QR codes and mini program codes with customizable styling and parameters. WeChat provides three different interfaces for QR code generation, each with specific use cases and limitations.

Capabilities

QR Code Service Interface

Main service for generating mini program codes and traditional QR codes with various customization options.

public interface WxMaQrcodeService {
    // Interface A - Mini Program Codes (Limited quantity)
    File createWxaCode(String path) throws WxErrorException;
    File createWxaCode(String path, int width) throws WxErrorException;
    File createWxaCode(String path, String envVersion, int width, boolean autoColor, 
                       WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException;
    
    byte[] createWxaCodeBytes(String path, String envVersion, int width, boolean autoColor,
                              WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException;
    
    // Interface B - Unlimited Mini Program Codes  
    File createWxaCodeUnlimit(String scene, String page) throws WxErrorException;
    File createWxaCodeUnlimit(String scene, String page, String saveDir) throws WxErrorException;
    File createWxaCodeUnlimit(String scene, String page, boolean checkPath, String envVersion,
                              int width, boolean autoColor, WxMaCodeLineColor lineColor,
                              boolean isHyaline) throws WxErrorException;
    
    byte[] createWxaCodeUnlimitBytes(String scene, String page, boolean checkPath, 
                                     String envVersion, int width, boolean autoColor,
                                     WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException;
    
    // Interface C - Traditional QR Codes (Limited quantity)
    File createQrcode(String path, int width) throws WxErrorException;
    byte[] createQrcodeBytes(String path, int width) throws WxErrorException;
    File createQrcode(String path, int width, String saveDir) throws WxErrorException;
}

QR Code Styling

Customization options for QR code appearance and behavior.

public class WxMaCodeLineColor implements Serializable {
    private String r;    // Red component (0-255)
    private String g;    // Green component (0-255) 
    private String b;    // Blue component (0-255)
    
    public WxMaCodeLineColor();
    public WxMaCodeLineColor(String r, String g, String b);
    
    // Getters and setters
    public String getR();
    public void setR(String r);
    public String getG();
    public void setG(String g);
    public String getB();
    public void setB(String b);
    
    // Utility methods
    public String toJson();
    public static WxMaCodeLineColor fromJson(String json);
    
    // Predefined colors
    public static WxMaCodeLineColor black() { return new WxMaCodeLineColor("0", "0", "0"); }
    public static WxMaCodeLineColor white() { return new WxMaCodeLineColor("255", "255", "255"); }
    public static WxMaCodeLineColor red() { return new WxMaCodeLineColor("255", "0", "0"); }
    public static WxMaCodeLineColor green() { return new WxMaCodeLineColor("0", "255", "0"); }
    public static WxMaCodeLineColor blue() { return new WxMaCodeLineColor("0", "0", "255"); }
}

Interface Differences & Use Cases

Interface A - Mini Program Codes (createWxaCode)

  • Limit: Combined with Interface C, maximum 100,000 codes total
  • Use Case: Static pages, limited scenarios
  • Parameters: Direct path to mini program page
  • Best For: Fixed navigation, menu items, static content

Interface B - Unlimited Codes (createWxaCodeUnlimit)

  • Limit: Unlimited generation
  • Use Case: Dynamic content, user-specific codes, mass generation
  • Parameters: Scene parameter (custom data up to 32 characters)
  • Best For: User profiles, dynamic content, personalized sharing

Interface C - Traditional QR Codes (createQrcode)

  • Limit: Combined with Interface A, maximum 100,000 codes total
  • Use Case: Traditional QR code appearance
  • Parameters: Direct path to mini program page
  • Best For: Print materials, traditional QR code scanners

Usage Examples

Basic Mini Program Code Generation

Simple Mini Program Code (Interface A)

try {
    // Basic mini program code - default settings
    File qrFile = wxService.getQrcodeService().createWxaCode("pages/index/index");
    
    // Save to specific directory with custom width
    File qrFile2 = wxService.getQrcodeService().createWxaCode(
        "pages/product/detail?id=123", 
        280  // Width in pixels
    );
    
    logger.info("Mini program code saved to: {}", qrFile2.getAbsolutePath());
    
} catch (WxErrorException e) {
    logger.error("Failed to create mini program code: {}", e.getMessage());
}

Advanced Mini Program Code with Styling

// Custom color for QR code lines  
WxMaCodeLineColor lineColor = new WxMaCodeLineColor("255", "0", "0"); // Red lines

try {
    File qrFile = wxService.getQrcodeService().createWxaCode(
        "pages/user/profile",           // Page path
        "release",                      // Environment: develop, trial, release
        430,                           // Width in pixels (default 430)
        false,                         // Auto color (false = use lineColor)
        lineColor,                     // Custom line color
        true                          // Transparent background
    );
    
    logger.info("Styled mini program code created: {}", qrFile.getAbsolutePath());
    
} catch (WxErrorException e) {
    logger.error("Failed to create styled code: {}", e.getMessage());
}

Get QR Code as Byte Array

try {
    byte[] qrBytes = wxService.getQrcodeService().createWxaCodeBytes(
        "pages/shop/product?id=456",
        "release",                      // Environment version
        300,                           // Width
        true,                          // Auto color
        null,                          // Line color (null when auto color = true)
        false                          // Not transparent
    );
    
    // Save to custom location or return to client
    Files.write(Paths.get("/custom/path/qrcode.png"), qrBytes);
    
    // Or return as HTTP response
    return ResponseEntity.ok()
        .contentType(MediaType.IMAGE_PNG)
        .body(qrBytes);
        
} catch (WxErrorException | IOException e) {
    logger.error("Failed to create QR code bytes: {}", e.getMessage());
}

Unlimited Mini Program Codes (Interface B)

User-Specific QR Codes

// Generate unlimited codes for each user
String userId = "user123";
String scene = "u=" + userId; // Scene parameter (max 32 characters)

try {
    File userQR = wxService.getQrcodeService().createWxaCodeUnlimit(
        scene,                          // Scene data
        "pages/user/invite"             // Landing page
    );
    
    // The mini program can retrieve scene data using:
    // wx.getLaunchOptionsSync().scene or wx.getEnterOptionsSync().scene
    
    logger.info("User QR code created: {}", userQR.getAbsolutePath());
    
} catch (WxErrorException e) {
    logger.error("Failed to create user QR code: {}", e.getMessage());
}

Product QR Codes with Custom Styling

public byte[] generateProductQR(String productId, String color) {
    String scene = "pid=" + productId;
    
    // Parse color
    WxMaCodeLineColor lineColor = null;
    if ("red".equals(color)) {
        lineColor = WxMaCodeLineColor.red();
    } else if ("blue".equals(color)) {
        lineColor = WxMaCodeLineColor.blue(); 
    } else {
        lineColor = WxMaCodeLineColor.black();
    }
    
    try {
        return wxService.getQrcodeService().createWxaCodeUnlimitBytes(
            scene,                      // Product scene data
            "pages/product/detail",     // Product detail page
            true,                       // Check path validity
            "release",                  // Environment
            400,                        // Width
            false,                      // Manual color (use lineColor)
            lineColor,                  // Custom color
            true                        // Transparent background
        );
        
    } catch (WxErrorException e) {
        logger.error("Failed to create product QR: {}", e.getMessage());
        return null;
    }
}

Bulk QR Code Generation

@Service
public class QRCodeBulkService {
    
    @Async
    public void generateBulkUserCodes(List<String> userIds) {
        for (String userId : userIds) {
            try {
                String scene = "uid=" + userId;
                
                File qrFile = wxService.getQrcodeService().createWxaCodeUnlimit(
                    scene,
                    "pages/user/profile",
                    "/qrcodes/users/"           // Save directory
                );
                
                // Rename file to include user ID
                File namedFile = new File(qrFile.getParent(), "user_" + userId + ".png");
                qrFile.renameTo(namedFile);
                
                logger.info("Generated QR for user: {}", userId);
                
                // Small delay to avoid rate limiting
                Thread.sleep(100);
                
            } catch (WxErrorException | InterruptedException e) {
                logger.error("Failed to generate QR for user {}: {}", userId, e.getMessage());
            }
        }
    }
}

Traditional QR Codes (Interface C)

try {
    // Simple traditional QR code
    File traditionalQR = wxService.getQrcodeService().createQrcode(
        "pages/home/index",
        280                             // Width
    );
    
    // As byte array
    byte[] qrBytes = wxService.getQrcodeService().createQrcodeBytes(
        "pages/contact/us",
        300
    );
    
    logger.info("Traditional QR code created");
    
} catch (WxErrorException e) {
    logger.error("Failed to create traditional QR code: {}", e.getMessage());
}

Practical Examples

E-commerce Product QR Codes

@RestController
@RequestMapping("/api/qr")
public class QRCodeController {
    
    @GetMapping("/product/{productId}")
    public ResponseEntity<byte[]> getProductQR(@PathVariable String productId,
                                               @RequestParam(defaultValue = "430") int width,
                                               @RequestParam(defaultValue = "false") boolean transparent) {
        try {
            String scene = "pid=" + productId + "&src=qr";
            
            byte[] qrBytes = wxService.getQrcodeService().createWxaCodeUnlimitBytes(
                scene,
                "pages/product/detail",
                true,                   // Check path
                "release",              // Environment
                width,
                true,                   // Auto color
                null,
                transparent
            );
            
            return ResponseEntity.ok()
                .contentType(MediaType.IMAGE_PNG)
                .header("Cache-Control", "public, max-age=86400") // Cache 1 day
                .body(qrBytes);
                
        } catch (WxErrorException e) {
            logger.error("Failed to generate product QR: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}

User Invitation System

@Service
public class InvitationService {
    
    public String generateInviteQR(String inviterId, String campaignId) {
        String scene = String.format("inv=%s&cmp=%s", inviterId, campaignId);
        
        // Validate scene length (max 32 characters)
        if (scene.length() > 32) {
            // Use shorter encoding or hash
            scene = "inv=" + hashCode(inviterId + campaignId);
        }
        
        try {
            File qrFile = wxService.getQrcodeService().createWxaCodeUnlimit(
                scene,
                "pages/invite/landing",
                "/tmp/invites/"
            );
            
            // Upload to CDN or cloud storage
            String qrUrl = uploadToCDN(qrFile);
            
            // Store mapping for analytics
            inviteRepository.save(new Invite(inviterId, campaignId, scene, qrUrl));
            
            return qrUrl;
            
        } catch (WxErrorException e) {
            logger.error("Failed to generate invite QR: {}", e.getMessage());
            throw new QRGenerationException("Could not generate invitation QR code");
        }
    }
    
    private String hashCode(String input) {
        // Simple hash for scene parameter
        return Integer.toHexString(input.hashCode()).substring(0, 8);
    }
}

Event Check-in QR Codes

@Component
public class EventQRGenerator {
    
    public Map<String, Object> generateEventQRs(String eventId, List<String> sessions) {
        Map<String, Object> result = new HashMap<>();
        List<String> qrUrls = new ArrayList<>();
        
        for (String sessionId : sessions) {
            try {
                String scene = "evt=" + eventId + "&ses=" + sessionId;
                
                // Custom styling for events
                WxMaCodeLineColor eventColor = new WxMaCodeLineColor("0", "123", "255"); // Blue
                
                byte[] qrBytes = wxService.getQrcodeService().createWxaCodeUnlimitBytes(
                    scene,
                    "pages/event/checkin",
                    true,                   // Check path
                    "release",
                    350,                    // Larger size for scanning
                    false,                  // Custom color
                    eventColor,             // Event brand color
                    false                   // Solid background
                );
                
                // Save with descriptive name
                String filename = String.format("event_%s_session_%s.png", eventId, sessionId);
                String qrPath = saveQRCode(qrBytes, filename);
                qrUrls.add(qrPath);
                
            } catch (WxErrorException e) {
                logger.error("Failed to generate QR for event {} session {}: {}", 
                           eventId, sessionId, e.getMessage());
            }
        }
        
        result.put("eventId", eventId);
        result.put("qrCodes", qrUrls);
        result.put("count", qrUrls.size());
        
        return result;
    }
}

Error Handling

public class QRCodeService {
    
    public byte[] generateQRWithFallback(String scene, String page) {
        try {
            // Try unlimited interface first (preferred)
            return wxService.getQrcodeService().createWxaCodeUnlimitBytes(
                scene, page, true, "release", 430, true, null, false
            );
            
        } catch (WxErrorException e) {
            int errorCode = e.getError().getErrorCode();
            
            switch (errorCode) {
                case 45009:
                    logger.warn("API quota exceeded for unlimited codes");
                    // Fall back to limited interface
                    return generateLimitedQR(page);
                    
                case 41030:
                    logger.error("Invalid scene parameter: {}", scene);
                    throw new IllegalArgumentException("Invalid scene parameter");
                    
                case 45006:
                    logger.error("Invalid page path: {}", page);
                    throw new IllegalArgumentException("Invalid page path");
                    
                default:
                    logger.error("QR generation failed: {} - {}", 
                               errorCode, e.getError().getErrorMsg());
                    throw new QRGenerationException("Failed to generate QR code", e);
            }
        }
    }
    
    private byte[] generateLimitedQR(String page) {
        try {
            return wxService.getQrcodeService().createWxaCodeBytes(
                page, "release", 430, true, null, false
            );
        } catch (WxErrorException e) {
            logger.error("Fallback QR generation also failed: {}", e.getMessage());
            throw new QRGenerationException("All QR generation methods failed", e);
        }
    }
}

Performance Optimization

@Service
public class OptimizedQRService {
    
    private final RedisTemplate<String, byte[]> redisTemplate;
    private final ExecutorService qrExecutor = Executors.newFixedThreadPool(5);
    
    @Cacheable(value = "qrcodes", key = "#scene + '_' + #page + '_' + #width")
    public byte[] getCachedQR(String scene, String page, int width) {
        try {
            return wxService.getQrcodeService().createWxaCodeUnlimitBytes(
                scene, page, true, "release", width, true, null, false
            );
        } catch (WxErrorException e) {
            logger.error("QR generation failed: {}", e.getMessage());
            return null;
        }
    }
    
    @Async
    public CompletableFuture<String> generateQRAsync(String scene, String page) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                File qrFile = wxService.getQrcodeService().createWxaCodeUnlimit(scene, page);
                return uploadToStorage(qrFile);
            } catch (WxErrorException e) {
                logger.error("Async QR generation failed: {}", e.getMessage());
                return null;
            }
        }, qrExecutor);
    }
}

This QR code service provides comprehensive code generation capabilities with proper error handling, caching strategies, and support for all WeChat QR code interfaces.

Install with Tessl CLI

npx tessl i tessl/maven-com-github-binarywang--weixin-java-miniapp

docs

analytics.md

cloud-development.md

configuration.md

core-services.md

development-tools.md

ecommerce.md

index.md

live-streaming.md

logistics.md

media-content.md

messaging.md

qr-codes.md

user-management.md

tile.json